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

  1. Set the credential env var directly (TENANT_KEY / TENANT_SECRET) to a valid 32-50 char value.
  2. Or set the file variant (TENANT_KEY_FILE / TENANT_SECRET_FILE) to the path of a regular readable file containing the value.
  3. Inspect the pod/container env (`kubectl exec ... env | grep TENANT`) to confirm which variable is missing.
  4. 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

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


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)