Skip to content

fix: preserve string-typed params as raw strings instead of parsing as JSON#32

Open
m11y wants to merge 1 commit into
volcengine:masterfrom
m11y:fix/preserve-string-params
Open

fix: preserve string-typed params as raw strings instead of parsing as JSON#32
m11y wants to merge 1 commit into
volcengine:masterfrom
m11y:fix/preserve-string-params

Conversation

@m11y
Copy link
Copy Markdown

@m11y m11y commented Mar 23, 2026

Problem

When a CLI parameter value looks like valid JSON (starts with { or [), ParseToJsonArrayOrObject deserializes it into a Go map/slice. The SDK's volcenginequery.BuildHandler then serializes the map as flattened query params:

PolicyDocument.Statement.0.Effect=Allow&PolicyDocument.Statement.0.Action.0=volcSMS:SendSms&...

This breaks APIs that expect the parameter to be a raw JSON string, such as IAM CreatePolicy's PolicyDocument:

# Always fails with "InvalidPolicy.Structure: Document is not a valid JSON string."
ve iam CreatePolicy --PolicyName MyPolicy --PolicyDocument '{"Statement":[{"Effect":"Allow","Action":["tos:*"],"Resource":["*"]}]}'

Root Cause

In cmd_action.go, the parameter parsing loop unconditionally attempts JSON deserialization on all non-body flag values (line 103). There is no check for whether the API actually expects a structured object or a plain string.

Fix

Use the existing API metadata (metatype) to look up each parameter's declared type. If the type is "string", skip ParseToJsonArrayOrObject and pass the value as-is. This is a minimal, targeted fix:

  • Added GetApiMeta() to RootSupport to expose per-action type metadata
  • Added isStringParam() helper that checks if a parameter is declared as "string" type
  • Modified the doAction parameter loop to skip JSON parsing for string-typed params
  • Added unit tests for isStringParam

Parameters without type metadata (i.e., ApiMeta is nil) retain the existing behavior — JSON parsing is still attempted as a best-effort heuristic.

Test Plan

  • go build ./... passes
  • Unit tests for isStringParam pass
  • Manual test: ve iam CreatePolicy --PolicyDocument '{"Statement":[...]}' should succeed

…s JSON

When a CLI parameter value looks like valid JSON (e.g. starts with '{'),
ParseToJsonArrayOrObject deserializes it into a Go map. The SDK then
serializes the map as flattened query params (e.g.
PolicyDocument.Statement.0.Effect=Allow). This breaks APIs like IAM
CreatePolicy where PolicyDocument must be a raw JSON string.

Fix: check the parameter's declared type from the API metadata. If the
type is "string", skip JSON parsing and pass the value as-is.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@m11y
Copy link
Copy Markdown
Author

m11y commented Apr 1, 2026

Hey @xuyaming0800, hope youre doing well!

I submitted this PR a while ago and just wanted to gently check in to see if youve had a chance to take a look. No rush at all — I know everyone has a lot on their plate.

Happy to make any changes or clarifications if needed. Thanks so much for your time and for maintaining this project!

@m11y
Copy link
Copy Markdown
Author

m11y commented Apr 1, 2026

Hey @xuyaming0800, hope you're doing well!

I submitted this PR a while ago and just wanted to gently check in to see if you've had a chance to take a look. No rush at all — I know everyone has a lot on their plate.

Happy to make any changes or clarifications if needed. Thanks so much for your time and for maintaining this project!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant