{"record":{"id":"d47d9880a59d5857","repo":"iflytek/astron-agent","slug":"s-or-s-is-required","errorCode":null,"errorMessage":"%s or %s is required","messagePattern":"(.+?) or (.+?) is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"core/tenant/config/bootstrap_credentials.go","lineNumber":94,"sourceCode":"\t\treturn errors.New(\"TENANT_KEY and TENANT_SECRET must be distinct values\")\n\t}\n\tif credentials.APIKey == LegacyTenantKey || credentials.Secret == LegacyTenantSecret {\n\t\treturn errors.New(\"published legacy tenant credentials cannot be used\")\n\t}\n\treturn nil\n}\n\nfunc credentialFromEnvironmentOrFile(valueEnvironment, fileEnvironment string) (string, error) {\n\tif value := strings.TrimSpace(os.Getenv(valueEnvironment)); value != \"\" {\n\t\tif err := validateCredential(valueEnvironment, value); err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t\treturn value, nil\n\t}\n\n\tfileName := strings.TrimSpace(os.Getenv(fileEnvironment))\n\tif fileName == \"\" {\n\t\treturn \"\", fmt.Errorf(\"%s or %s is required\", valueEnvironment, fileEnvironment)\n\t}\n\tvalue, err := readCredentialFile(fileName)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"load %s: %w\", fileEnvironment, err)\n\t}\n\tif err := validateCredential(valueEnvironment, value); err != nil {\n\t\treturn \"\", err\n\t}\n\treturn value, nil\n}\n\nfunc readCredentialFile(fileName string) (string, error) {\n\tfile, err := openCredentialFileNoFollow(fileName)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tdefer func() {\n\t\t_ = file.Close()","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/core/tenant/config/bootstrap_credentials.go#L76-L112","documentation":"credentialFromEnvironmentOrFile resolves a bootstrap credential from a direct env var (e.g. TENANT_KEY) or, failing that, a *_FILE env var pointing at a file (e.g. TENANT_KEY_FILE). When both are empty/unset it returns '<NAME> or <NAME>_FILE is required', because there is no way to obtain the credential.","triggerScenarios":"LoadTenantBootstrapCredentials → credentialFromEnvironmentOrFile(\"TENANT_KEY\",\"TENANT_KEY_FILE\") (or the SECRET pair) where the value env var is empty/whitespace and the file env var is empty/whitespace.","commonSituations":"Kubernetes Secret not mounted, so neither env var is injected; typo'd env var name in the manifest; docker run without -e flags; _FILE-style secret injection disabled in the chart.","solutions":["Set the credential env var directly (TENANT_KEY / TENANT_SECRET) to a valid 32-50 char value.","Or set the file variant (TENANT_KEY_FILE / TENANT_SECRET_FILE) to the path of a regular readable file containing the value.","Inspect the pod/container env (`kubectl exec ... env | grep TENANT`) to confirm which variable is missing.","Fix the Secret reference/mount in the deployment so the variable is actually injected."],"exampleFix":"// before (docker run)\ndocker run astron/tenant   # no TENANT_* vars\n\n// after\ndocker run -e TENANT_KEY=$TENANT_KEY -e TENANT_SECRET=$TENANT_SECRET astron/tenant","handlingStrategy":"validation","validationCode":"for _, v := range []string{\"TENANT_KEY\", \"TENANT_SECRET\"} {\n\tif os.Getenv(v) == \"\" && os.Getenv(v+\"_FILE\") == \"\" {\n\t\treturn fmt.Errorf(\"%s or %s must be set\", v, v+\"_FILE\")\n\t}\n}","typeGuard":null,"tryCatchPattern":"tenantBootstrap, err := config.LoadTenantBootstrapCredentials()\nif err != nil {\n\tlog.Fatalf(\"bootstrap credentials missing: %v\", err)\n}","preventionTips":["Add env-var presence checks to CI or a startup preflight script.","Use secretKeyRef in Kubernetes so vars are injected declaratively.","Verify injected env inside the container after every manifest change."],"tags":["env","credentials","config","go"],"backgroundTag":"missing-env-var","analyzedSha":"5e758547a83371a5a4b29dadf4ac03e8dd527635","analyzedAt":"2026-09-12T08:03:51.356Z","contentChangedAt":"2026-09-12T08:03:51.356Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}