{"record":{"id":"920c3cf93dfec139","repo":"larksuite/cli","slug":"l3-meta-access-tokens-contains-invalid-value-q","errorCode":null,"errorMessage":"L3: _meta.access_tokens contains invalid value %q (allowed: user, bot)","messagePattern":"L3: _meta\\.access_tokens contains invalid value %q \\(allowed: user, bot\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/schema/lint.go","lineNumber":105,"sourceCode":"\t}\n\n\t// `yes` lives at inputSchema.properties.yes (sibling of params/data),\n\t// injected only for risk == RiskHighRiskWrite.\n\thasYes := false\n\tif env.InputSchema != nil && env.InputSchema.Properties != nil {\n\t\t_, hasYes = env.InputSchema.Properties.Map[\"yes\"]\n\t}\n\twantYes := env.Meta.Risk == core.RiskHighRiskWrite\n\tif hasYes != wantYes {\n\t\terrs = append(errs, fmt.Errorf(\"L3: inputSchema `yes` property=%v inconsistent with risk=%q\", hasYes, env.Meta.Risk))\n\t}\n\n\tif len(env.Meta.AccessTokens) == 0 {\n\t\terrs = append(errs, errors.New(\"L3: _meta.access_tokens must not be empty\"))\n\t}\n\tfor _, t := range env.Meta.AccessTokens {\n\t\tif !validAccessTokens[t] {\n\t\t\terrs = append(errs, fmt.Errorf(\"L3: _meta.access_tokens contains invalid value %q (allowed: user, bot)\", t))\n\t\t}\n\t}\n\n\treturn errs\n}\n\n// walkForL2 recursively applies per-field L2 checks (format:binary on\n// non-string; minimum>=maximum) plus the sub-object required-exists invariant.\n// Required only matters on object-typed Properties (e.g. the params / data\n// wrappers); leaf scalars ignore it.\nfunc walkForL2(props *OrderedProps, errs *[]error) {\n\tif props == nil {\n\t\treturn\n\t}\n\tfor _, k := range props.Order {\n\t\tp := props.Map[k]\n\t\tif p.Format == \"binary\" && p.Type != \"string\" {\n\t\t\t*errs = append(*errs, fmt.Errorf(\"L2: field %q has format: binary but type = %q (want string)\", k, p.Type))","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/schema/lint.go#L87-L123","documentation":"L3 lint rule requiring every envelope's Meta.AccessTokens to contain only `user` and/or `bot`. Access tokens describe which Lark identities the method may be called with; an unrecognized value would produce an invalid _meta.access_tokens in the published schema.","triggerScenarios":"lintEnvelope is called on an envelope where Meta.AccessTokens is empty (separate L3 error) or contains a token string other than \"user\" or \"bot\" (typo, capitalization like \"User\", or a made-up identity).","commonSituations":"Typo when hand-writing envelope metadata; copy-pasted token list from another system; renaming an identity without updating all envelopes.","solutions":["Replace the invalid value with \"user\", \"bot\", or both","Fix casing to exact lowercase \"user\"/\"bot\"","Check validAccessTokens in internal/schema for the allowed set"],"exampleFix":"// before\nMeta: {AccessTokens: []string{\"User\"}}\n// after\nMeta: {AccessTokens: []string{\"user\", \"bot\"}}","handlingStrategy":"validation","validationCode":"var validAccessTokens = map[string]bool{\"user\": true, \"bot\": true}\nfor _, t := range env.Meta.AccessTokens {\n  if !validAccessTokens[t] {\n    t.Errorf(\"envelope %s: invalid access token %q\", env.Name, t)\n  }\n}\nif len(env.Meta.AccessTokens) == 0 {\n  t.Errorf(\"envelope %s: access_tokens empty\", env.Name)\n}","typeGuard":"func validAccessToken(s string) bool { return s == \"user\" || s == \"bot\" }","tryCatchPattern":null,"preventionTips":["Use only the literal strings \"user\" and \"bot\" for access tokens","Always list at least one access token per envelope","Define token constants once and reference them instead of raw strings","Run the schema lint tests after editing envelope metadata"],"tags":["schema","lint","metadata"],"backgroundTag":"schema-validation-failed","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}