{"record":{"id":"b8864166aa031008","repo":"nektos/act","slug":"container-credentials-cannot-be-empty","errorCode":null,"errorMessage":"container.credentials cannot be empty","messagePattern":"container\\.credentials cannot be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/runner/run_context.go","lineNumber":1122,"sourceCode":"\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\n\t}\n\tif len(creds) != 2 {\n\t\terr = fmt.Errorf(\"invalid property count for key 'credentials:'\")\n\t\treturn\n\t}\n\n\tee := rc.NewExpressionEvaluator(ctx)\n\tif username = ee.Interpolate(ctx, creds[\"username\"]); username == \"\" {\n\t\terr = fmt.Errorf(\"failed to interpolate credentials.username\")","sourceCodeStart":1104,"sourceCodeEnd":1140,"githubUrl":"https://github.com/nektos/act/blob/4f411281417e88660bea1c1a1749aa71ae0bd60f/pkg/runner/run_context.go#L1104-L1140","documentation":"A defensive re-check after interpolation: the raw (pre-interpolation) `container.credentials` map has an empty username or password value. In practice the earlier empty-after-interpolation checks usually fire first, but if the raw value itself is empty (and interpolation is a no-op on empty strings) this guard rejects it.","triggerScenarios":"`credentials.username:` or `credentials.password:` is literally empty in the YAML (e.g. `password:` with nothing after it) while the map still has exactly two keys.","commonSituations":"Placeholder YAML with empty credential values awaiting CI injection; a `${{ }}` string that was stripped from the file; trailing whitespace/indentation mistakes leaving the value nil.","solutions":["Fill in real values or expressions for both username and password.","If auth is not needed, delete the `credentials:` block so handleCredentials returns the config-secret fallback path.","Use a secret reference rather than committing empty placeholders."],"exampleFix":"# before\ncredentials:\n  username: ci\n  password:        # empty\n# after\ncredentials:\n  username: ci\n  password: ${{ secrets.REG_PWD }}","handlingStrategy":"validation","validationCode":"grep -RniE 'password:\\s*$|username:\\s*$' .github/workflows/ && echo 'empty credential value found' || echo ok","typeGuard":null,"tryCatchPattern":null,"preventionTips":["No empty credential placeholders in committed YAML.","If auth is unnecessary, omit the credentials block."],"tags":["container","credentials","workflow-syntax"],"backgroundTag":null,"analyzedSha":"4f411281417e88660bea1c1a1749aa71ae0bd60f","analyzedAt":"2026-08-15T09:19:46.307Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}