{"record":{"id":"98e84f343e74ea97","repo":"nektos/act","slug":"failed-to-interpolate-credentials-username","errorCode":null,"errorMessage":"failed to interpolate credentials.username","messagePattern":"failed to interpolate credentials\\.username","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/runner/run_context.go","lineNumber":1140,"sourceCode":"\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\")\n\t\treturn\n\t}\n\n\tif password = ee.Interpolate(ctx, creds[\"password\"]); password == \"\" {\n\t\terr = fmt.Errorf(\"failed to interpolate credentials.password\")\n\t\treturn\n\t}\n\n\treturn\n}\n\n// GetServiceBindsAndMounts returns the binds and mounts for the service container, resolving paths as appropriate\nfunc (rc *RunContext) GetServiceBindsAndMounts(svcVolumes []string) ([]string, map[string]string) {\n\tif rc.Config.ContainerDaemonSocket == \"\" {\n\t\trc.Config.ContainerDaemonSocket = \"/var/run/docker.sock\"\n\t}\n\tbinds := []string{}\n\tif rc.Config.ContainerDaemonSocket != \"-\" {","sourceCodeStart":1122,"sourceCodeEnd":1158,"githubUrl":"https://github.com/nektos/act/blob/4f411281417e88660bea1c1a1749aa71ae0bd60f/pkg/runner/run_context.go#L1122-L1158","documentation":"Interpolating a service container's `credentials.username` produced an empty string. After the two-key check passes, the value is run through the expression evaluator; empty output (missing secret or empty literal) aborts service startup.","triggerScenarios":"`services.<id>.credentials.username:` is `${{ secrets.X }}` where X was not supplied to act, or is an empty literal.","commonSituations":"Private-registry service images requiring auth the local act run never provides; secret name mismatch; secrets file not loaded.","solutions":["Pass the secret via `act -s <NAME>=<value>` or `--secret-file`.","Verify the secret name matches exactly (case-sensitive).","If the service image is public, drop the credentials block — it is only needed for private registries."],"exampleFix":"# before\nservices:\n  db:\n    image: private.example.com/pg\n    credentials: { username: '${{ secrets.PG_USER }}', password: 'x' }\n# run: act push   (secret missing -> empty username)\n# after\nact push -s PG_USER=ci -s PG_PWD=secret","handlingStrategy":"validation","validationCode":"act --secret-file .secrets --dryrun  # confirms all referenced secrets are provided","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Centralize required secrets per workflow in one file.","Use public base images locally to avoid registry auth entirely."],"tags":["services","credentials","secrets","expressions"],"backgroundTag":null,"analyzedSha":"4f411281417e88660bea1c1a1749aa71ae0bd60f","analyzedAt":"2026-08-15T09:19:46.307Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}