{"record":{"id":"a6d13ce72dadb32b","repo":"nektos/act","slug":"invalid-property-count-for-key-credentials","errorCode":null,"errorMessage":"invalid property count for key 'credentials:'","messagePattern":"invalid property count for key 'credentials:'","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/runner/run_context.go","lineNumber":1107,"sourceCode":"\t\t\trunID, _ = strconv.ParseInt(rid, 10, 64)\n\t\t}\n\t\tactionsRuntimeToken, _ = common.CreateAuthorizationToken(runID, runID, runID)\n\t}\n\tenv[\"ACTIONS_RUNTIME_TOKEN\"] = actionsRuntimeToken\n}\n\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","sourceCodeStart":1089,"sourceCodeEnd":1125,"githubUrl":"https://github.com/nektos/act/blob/4f411281417e88660bea1c1a1749aa71ae0bd60f/pkg/runner/run_context.go#L1089-L1125","documentation":"The job's `container.credentials:` map does not contain exactly two keys. act requires the map to hold precisely `username` and `password`; anything else — one key, three keys, or differently named keys — fails this check before any Docker registry authentication is attempted.","triggerScenarios":"`jobs.<id>.container.credentials:` in the workflow has extra keys, only one of username/password, or keys with different names; also triggered when YAML indentation folds another map under credentials.","commonSituations":"Adding a `server:` or `registry:` key next to username/password (GitHub only documents username/password); forgetting one half of the pair; pasting docker login CLI flags into the credentials block.","solutions":["Make `credentials:` contain exactly `username:` and `password:` and nothing else.","If you need to target a non-default registry, that is configured via the image reference or act flags, not extra credential keys.","Re-check YAML indentation so no sibling keys are swallowed into the credentials map."],"exampleFix":"# before\ncontainer:\n  image: registry.example.com/app\n  credentials:\n    username: ci\n    password: ${{ secrets.REG_PWD }}\n    registry: registry.example.com  # third key -> error\n# after\ncontainer:\n  image: registry.example.com/app\n  credentials:\n    username: ci\n    password: ${{ secrets.REG_PWD }}","handlingStrategy":"validation","validationCode":"# assert exactly two credential keys\npython3 - <<'EOF'\nimport yaml,sys\nwf=yaml.safe_load(open('.github/workflows/ci.yml'))\nfor j in wf.get('jobs',{}).values():\n    c=(j.get('container') or {}).get('credentials')\n    if c is not None and set(c)!= {'username','password'}:\n        sys.exit(f\"bad credentials keys: {set(c)}\")\nEOF","typeGuard":null,"tryCatchPattern":null,"preventionTips":["credentials maps only ever hold username and password.","Automate this YAML check in CI lint."],"tags":["container","credentials","workflow-syntax","registry-auth"],"backgroundTag":null,"analyzedSha":"4f411281417e88660bea1c1a1749aa71ae0bd60f","analyzedAt":"2026-08-15T09:19:46.307Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}