{"record":{"id":"073f969145d1ba87","repo":"nektos/act","slug":"failed-to-interpolate-container-credentials-userna","errorCode":null,"errorMessage":"failed to interpolate container.credentials.username","messagePattern":"failed to interpolate container\\.credentials\\.username","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/runner/run_context.go","lineNumber":1113,"sourceCode":"\nfunc (rc *RunContext) handleCredentials(ctx context.Context) (string, string, error) {\n\t// TODO: remove below 2 lines when we can release act with breaking changes\n\tusername := rc.Config.Secrets[\"DOCKER_USERNAME\"]\n\tpassword := rc.Config.Secrets[\"DOCKER_PASSWORD\"]\n\n\tcontainer := rc.Run.Job().Container()\n\tif container == nil || container.Credentials == nil {\n\t\treturn username, password, nil\n\t}\n\n\tif container.Credentials != nil && len(container.Credentials) != 2 {\n\t\terr := fmt.Errorf(\"invalid property count for key 'credentials:'\")\n\t\treturn \"\", \"\", err\n\t}\n\n\tee := rc.NewExpressionEvaluator(ctx)\n\tif username = ee.Interpolate(ctx, container.Credentials[\"username\"]); username == \"\" {\n\t\terr := fmt.Errorf(\"failed to interpolate container.credentials.username\")\n\t\treturn \"\", \"\", err\n\t}\n\tif password = ee.Interpolate(ctx, container.Credentials[\"password\"]); password == \"\" {\n\t\terr := fmt.Errorf(\"failed to interpolate container.credentials.password\")\n\t\treturn \"\", \"\", err\n\t}\n\n\tif container.Credentials[\"username\"] == \"\" || container.Credentials[\"password\"] == \"\" {\n\t\terr := fmt.Errorf(\"container.credentials cannot be empty\")\n\t\treturn \"\", \"\", err\n\t}\n\n\treturn username, password, nil\n}\n\nfunc (rc *RunContext) handleServiceCredentials(ctx context.Context, creds map[string]string) (username, password string, err error) {\n\tif creds == nil {\n\t\treturn","sourceCodeStart":1095,"sourceCodeEnd":1131,"githubUrl":"https://github.com/nektos/act/blob/4f411281417e88660bea1c1a1749aa71ae0bd60f/pkg/runner/run_context.go#L1095-L1131","documentation":"Interpolating `container.credentials.username` produced an empty string. After confirming the credentials map has exactly two keys, act runs the value through the expression evaluator; if the result is empty (the raw value was empty, or the `${{ }}` expression resolved to empty/missing), this error is returned.","triggerScenarios":"`jobs.<id>.container.credentials.username:` is an expression referencing an undefined secret (e.g. secrets.REG_USER not passed to act), or is literally empty/whitespace.","commonSituations":"Running act without `-s REG_USER=...` (act does not read GitHub secrets automatically); secret name typo between workflow and the `-s` flag or .secrets file; referencing an org-level variable unavailable locally.","solutions":["Pass the secret to act: `act -s REG_USER=... -s REG_PWD=...` or load via `--secret-file`.","Check for typos between the secret name in the workflow and the one supplied on the CLI.","Verify the expression resolves non-empty (echo it in a prior step or run with --verbose to see evaluation).","Set a placeholder username locally if the registry does not need auth in your environment, or drop the credentials block entirely."],"exampleFix":"# before\n# workflow: username: ${{ secrets.REG_USER }}\n# run: act push\n# after\nact push -s REG_USER=ci -s REG_PWD=tokengh_...","handlingStrategy":"validation","validationCode":"act -s REG_USER=ci -s REG_PWD=xxx --dryrun   # secrets must be present before real run","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always invoke act with --secret-file rather than ad-hoc -s flags.","Keep secret names identical between CI and local runs.","Dry-run first to surface missing secrets early."],"tags":["container","credentials","secrets","expressions"],"backgroundTag":null,"analyzedSha":"4f411281417e88660bea1c1a1749aa71ae0bd60f","analyzedAt":"2026-08-15T09:19:46.307Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}