iflytek/astron-agent · critical
or is required
Error message
%s or %s is required
What it means
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.
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.
Example fix
// before (docker run) docker run astron/tenant # no TENANT_* vars // after docker run -e TENANT_KEY=$TENANT_KEY -e TENANT_SECRET=$TENANT_SECRET astron/tenant
Defensive patterns
Strategy: validation
Validate before calling
for _, v := range []string{"TENANT_KEY", "TENANT_SECRET"} {
if os.Getenv(v) == "" && os.Getenv(v+"_FILE") == "" {
return fmt.Errorf("%s or %s must be set", v, v+"_FILE")
}
} Try / catch
tenantBootstrap, err := config.LoadTenantBootstrapCredentials()
if err != nil {
log.Fatalf("bootstrap credentials missing: %v", err)
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.
Related errors
- load tenant bootstrap credentials failed
- TENANT_ID must remain
- -1
- RUN_LINK_URL is not set
- Config file not found
AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12).
Data as JSON: /api/errors/d47d9880a59d5857.
Report an issue: GitHub.
Appendix: source
Thrown at core/tenant/config/bootstrap_credentials.go:94
return errors.New("TENANT_KEY and TENANT_SECRET must be distinct values")
}
if credentials.APIKey == LegacyTenantKey || credentials.Secret == LegacyTenantSecret {
return errors.New("published legacy tenant credentials cannot be used")
}
return nil
}
func credentialFromEnvironmentOrFile(valueEnvironment, fileEnvironment string) (string, error) {
if value := strings.TrimSpace(os.Getenv(valueEnvironment)); value != "" {
if err := validateCredential(valueEnvironment, value); err != nil {
return "", err
}
return value, nil
}
fileName := strings.TrimSpace(os.Getenv(fileEnvironment))
if fileName == "" {
return "", fmt.Errorf("%s or %s is required", valueEnvironment, fileEnvironment)
}
value, err := readCredentialFile(fileName)
if err != nil {
return "", fmt.Errorf("load %s: %w", fileEnvironment, err)
}
if err := validateCredential(valueEnvironment, value); err != nil {
return "", err
}
return value, nil
}
func readCredentialFile(fileName string) (string, error) {
file, err := openCredentialFileNoFollow(fileName)
if err != nil {
return "", err
}
defer func() {
_ = file.Close()View on GitHub (pinned to 5e758547a8)