larksuite/cli · error
L3: _meta.access_tokens must not be empty
Error message
L3: _meta.access_tokens must not be empty
What it means
The L3 policy lint requires every envelope to declare at least one access token in Meta.AccessTokens, because the runtime must know whether the command runs as 'user' or 'bot' identity. An empty list means the envelope's identity policy was never specified, so the lint rejects it; values outside the allowed set {user, bot} are also rejected by the following loop.
Source
Thrown at internal/schema/lint.go:101
// ---- L3: cross-field self-consistency ----
dangerExpected := env.Meta.Risk == core.RiskWrite || env.Meta.Risk == core.RiskHighRiskWrite
if env.Meta.Danger != dangerExpected {
errs = append(errs, fmt.Errorf("L3: _meta.danger=%v inconsistent with risk=%q", env.Meta.Danger, env.Meta.Risk))
}
// `yes` lives at inputSchema.properties.yes (sibling of params/data),
// injected only for risk == RiskHighRiskWrite.
hasYes := false
if env.InputSchema != nil && env.InputSchema.Properties != nil {
_, hasYes = env.InputSchema.Properties.Map["yes"]
}
wantYes := env.Meta.Risk == core.RiskHighRiskWrite
if hasYes != wantYes {
errs = append(errs, fmt.Errorf("L3: inputSchema `yes` property=%v inconsistent with risk=%q", hasYes, env.Meta.Risk))
}
if len(env.Meta.AccessTokens) == 0 {
errs = append(errs, errors.New("L3: _meta.access_tokens must not be empty"))
}
for _, t := range env.Meta.AccessTokens {
if !validAccessTokens[t] {
errs = append(errs, fmt.Errorf("L3: _meta.access_tokens contains invalid value %q (allowed: user, bot)", t))
}
}
return errs
}
// walkForL2 recursively applies per-field L2 checks (format:binary on
// non-string; minimum>=maximum) plus the sub-object required-exists invariant.
// Required only matters on object-typed Properties (e.g. the params / data
// wrappers); leaf scalars ignore it.
func walkForL2(props *OrderedProps, errs *[]error) {
if props == nil {
return
}View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Add at least one valid access token to Meta.AccessTokens: "user", "bot", or both as appropriate for the command's identity needs.
- Align tokens with the declared Risk: high-risk writes typically need an explicit token decision and a matching `yes` confirmation property (the adjacent L3 check).
- Re-run the envelope lint suite to confirm the policy block passes.
Example fix
// before
Meta: &Meta{EnvelopeVersion: "1.0", Risk: core.RiskSafeRead}
// after
Meta: &Meta{EnvelopeVersion: "1.0", Risk: core.RiskSafeRead, AccessTokens: []string{"user"}} Defensive patterns
Strategy: validation
Validate before calling
func validateAccessTokens(m *Meta) error {
if len(m.AccessTokens) == 0 {
return errors.New("meta.access_tokens must include at least one of: user, bot")
}
return nil
} Type guard
if env.Meta != nil && len(env.Meta.AccessTokens) == 0 {
// handle: identity policy missing
} Try / catch
if err := lintEnvelope(env); err != nil {
// detect "access_tokens must not be empty" and add tokens
} Prevention
- Decide user vs bot identity for every command when declaring Risk.
- Keep AccessTokens and Risk in the same meta template so one is never forgotten.
- Only use the allowed values user and bot; anything else trips the adjacent validity loop.
When it happens
Trigger: Linting an envelope with Meta present but AccessTokens empty (len == 0), e.g. &Meta{EnvelopeVersion: "1.0", Risk: ...} without tokens.
Common situations: Authors fill in risk level but forget identity policy; meta structs generated from configs where the access_tokens key was missing; plugins copied from examples that predate the access-token requirement.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- L1: inputSchema must not be nil
- L1: inputSchema.properties must not be nil
- L1: outputSchema must not be nil
- L1: _meta must not be nil
- invalid identities entry %q: must be 'user' or 'bot'
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/a2ca25e125303625.
Report an issue: GitHub.