larksuite/cli · error
trailing data after JSON value: %w
Error message
trailing data after JSON value: %w
What it means
Same check as errorIndex 951, but here the second Decode failed with an error other than EOF (a JSON syntax error in the trailing bytes). decoderExpectEOF wraps that underlying error to report both the trailing-data condition and the parse failure. Callers wrap it into a typed --sheets/--values validation error.
Source
Thrown at shortcuts/sheets/lark_sheet_table_io.go:328
return "datetime64[ns]"
case "bool":
return "bool"
default:
return "object"
}
}
// decoderExpectEOF ensures the decoder has nothing left to read after a
// successful Decode. json.Decoder accepts trailing non-whitespace after the
// first JSON value (unlike json.Unmarshal), so a payload like `{...} trailing`
// would silently be treated as the leading object only. Use this after the
// first Decode to surface the trailing data as a validation error.
func decoderExpectEOF(dec *json.Decoder) error {
var trailing json.RawMessage
if err := dec.Decode(&trailing); err == nil {
return fmt.Errorf("trailing data after JSON value") //nolint:forbidigo // intermediate error; the caller wraps it into a typed --sheets/--values validation error
} else if !errors.Is(err, io.EOF) {
return fmt.Errorf("trailing data after JSON value: %w", err) //nolint:forbidigo // intermediate error; the caller wraps it into a typed --sheets/--values validation error
}
return nil
}
// tablePutSheetsSkeleton is the one-line --sheets shape inlined on a decode
// error, so the retry needs no --print-schema round trip. Field vocabulary
// mirrors tableSheetIn.
const tablePutSheetsSkeleton = `{"sheets":[{"name":"Sheet1","columns":["City","Revenue"],"dtypes":{"Revenue":"float64"},"data":[["SH",123.4],["BJ",56.7]],"start_cell":"A1"}]}`
// parseTablePutPayload reads --sheets (JSON, supports @file / stdin) into a
// validated payload. UseNumber keeps numeric cells as json.Number so large
// integers (order IDs, etc.) survive without precision loss or scientific
// notation. The wire shape (tableSheetIn: string columns + dtypes/formats maps
// + `data`) is normalized into the internal tableSheetSpec so the rest of the
// file (buildSheetMatrix, sheetCreateDims, …) is unaware of it. Network-free:
// safe from Validate and DryRun.
func parseTablePutPayload(runtime flagView) (*tablePayload, error) {
raw := strings.TrimSpace(runtime.Str("sheets"))View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Delete the malformed trailing fragment after the first complete JSON value
- Validate the payload with a JSON linter (jq . payload.json) before passing it
- Pass the payload via a file or properly quoted single argument to avoid shell mangling
Example fix
// before
--sheets '{"columns":[]} {,'
// after
--sheets '{"columns":[]}' Defensive patterns
Strategy: validation
Validate before calling
function assertValidJSON(s) { JSON.parse(s); return s; }
// run before invoking: assertValidJSON(payload) Type guard
function isParsableJSON(s) { try { JSON.parse(s); return true; } catch { return false; } } Try / catch
try {
await run(['lark','sheet','table-put','--sheets',payload]);
} catch (e) {
if (/trailing data after JSON value: /.test(e.message)) {
console.error('Payload has malformed trailing bytes; validate with jq:', e.message);
}
throw e;
} Prevention
- Validate payload files with `jq . payload.json` before passing them
- Read payloads from a single quoted argument or file, not from concatenated shell fragments
- Check heredocs/copy-paste for truncation or duplicated braces
When it happens
Trigger: Payload with malformed bytes after the first JSON value, e.g. '{...} ,,' or '{...} {' — the trailing fragment is itself invalid JSON, so Decode returns a syntax error instead of EOF.
Common situations: Truncated copy/paste leaving a partial second object; shell splitting arguments leaving stray '{' or ','; corrupted heredoc input.
Related errors
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/5b9b058b1d1e5451.
Report an issue: GitHub.