larksuite/cli · error

bool expects true/false, got %s

Error message

bool expects true/false, got %s

What it means

buildTypedCell requires a column declared "bool" to carry JSON true/false. Any other JSON value (string "true", number, null) fails this check; the caller adds row/column context and wraps it in a typed validation error.

Source

Thrown at shortcuts/sheets/lark_sheet_table_io.go:698

	switch col.Type {
	case "":
		// Type-less column: write the raw JSON scalar as-is so Lark Sheets
		// auto-detects the type (numeric → number, else text). json.Number is
		// kept verbatim for precision; an optional --styles number_format
		// controls display. This is the untyped --values behavior.
		cell["value"] = raw
	case "string":
		cell["value"] = stringifyCellValue(raw)
	case "number":
		n, ok := raw.(json.Number)
		if !ok {
			return nil, fmt.Errorf("number expects a numeric value, got %s", describeJSONType(raw)) //nolint:forbidigo // intermediate error; callers wrap it into a typed --sheets/--values validation error with row/column context
		}
		cell["value"] = n
	case "bool":
		b, ok := raw.(bool)
		if !ok {
			return nil, fmt.Errorf("bool expects true/false, got %s", describeJSONType(raw)) //nolint:forbidigo // intermediate error; callers wrap it into a typed --sheets/--values validation error with row/column context
		}
		cell["value"] = b
	case "date":
		str, ok := raw.(string)
		if !ok {
			return nil, fmt.Errorf("date expects an ISO yyyy-mm-dd string, got %s", describeJSONType(raw)) //nolint:forbidigo // intermediate error; callers wrap it into a typed --sheets/--values validation error with row/column context
		}
		serial, err := isoDateToSerial(str)
		if err != nil {
			return nil, err
		}
		cell["value"] = serial
	default:
		return nil, fmt.Errorf("unsupported type %q", col.Type) //nolint:forbidigo // intermediate error; callers wrap it into a typed --sheets/--values validation error with row/column context
	}
	return cell, nil
}

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Use unquoted JSON true/false literals
  2. Change the column dtype to "string" if "true"/"false" text is intentional
  3. Fill empty cells with explicit booleans or drop those rows

Example fix

// before
{"name":"Active","type":"bool","data":["true"]}
// after
{"name":"Active","type":"bool","data":[true]}
Defensive patterns

Strategy: validation

Validate before calling

function assertBoolColumn(col) {
  col.data.forEach((v, i) => {
    if (typeof v !== 'boolean') throw new Error(`column ${col.name} (bool): row ${i} value ${JSON.stringify(v)} is not true/false`);
  });
}

Type guard

function isJSONBool(v) { return typeof v === 'boolean'; }

Try / catch

try {
  await run(['lark','sheet','table-put','--sheets',payload]);
} catch (e) {
  if (/bool expects true\/false/.test(e.message)) {
    payload = payload.replace(/"(true|false)"/g, '$1'); // unquote booleans
  }
  throw e;
}

Prevention

When it happens

Trigger: Bool column given "true"/"false" as JSON strings (common when data passed through shells or CSV converters); null for empty cells.

Common situations: Quoting booleans because the payload was built by string templating; environment configs serializing bools as strings; null holes in data grids.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04). Data as JSON: /api/errors/07057f1126dca39f. Report an issue: GitHub.