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

  1. Delete the malformed trailing fragment after the first complete JSON value
  2. Validate the payload with a JSON linter (jq . payload.json) before passing it
  3. 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

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.