Bug: posts:create returns 401 while auth:check and accounts:health report valid credentials/account
Summary
zernio posts:create fails with Unauthorized / HTTP 401 even though:
zernio auth:check --pretty reports the API key is valid
zernio accounts:health --pretty reports the target Facebook account is healthy
- the account health response says
canPost: true, tokenValid: true, and needsReconnect: false
zernio media:upload succeeds with the same CLI/auth context
This makes the CLI state contradictory: account health says the account is postable, but every posts:create attempt is rejected with 401.
Environment
- CLI:
zernio --version → 0.3.0
- Package:
@zernio/cli 0.3.0
- Repo default branch checked:
zernio-dev/zernio-cli main
- Runtime: Linux CLI environment
- Target platform tested: Facebook page account (
mrgoon.info / MrGoon)
No API keys or tokens are included in this report.
Reproduction steps
- Verify CLI auth:
zernio auth:check --pretty
Actual result:
{
"success": true,
"message": "API key is valid"
}
- Check account health:
zernio accounts:health --pretty
Relevant target account result:
{
"platform": "facebook",
"username": "mrgoon.info",
"displayName": "MrGoon",
"status": "healthy",
"canPost": true,
"tokenValid": true,
"needsReconnect": false,
"issues": []
}
- Upload media:
zernio media:upload generated/2026-06-10/agents-resource-contention-harness_20260610-123446_382835.png
zernio media:upload tmp/leopardracer-fable-image.jpg
Actual result: both uploads succeeded and returned media URLs.
- Try publishing a Facebook post with two media URLs:
zernio posts:create \
--text "<facebook post body>" \
--accounts "<facebook-account-id>" \
--media "<media-url-1>,<media-url-2>" \
--pretty
Actual result:
{"error":true,"message":"Unauthorized","status":401}
- Retry with only one image:
zernio posts:create \
--text "<facebook post body>" \
--accounts "<facebook-account-id>" \
--media "<media-url-1>" \
--pretty
Actual result:
{"error":true,"message":"Unauthorized","status":401}
- Try creating a draft-only test post with no media:
zernio posts:create \
--text "test draft auth check - do not publish" \
--accounts "<facebook-account-id>" \
--draft \
--pretty
Actual result:
{"error":true,"message":"Unauthorized","status":401}
Expected behavior
One of these should happen:
posts:create succeeds because the account health endpoint says the API key and Facebook account are valid/postable; or
accounts:health should report the account as not postable, token invalid, missing permission, needing reconnect, or otherwise blocked; or
posts:create should return a more actionable error than a generic Unauthorized, e.g. which credential/token layer failed and whether the user must reconnect, refresh the API key, select another profile, or reauthorize page permissions.
Actual behavior
posts:create returns only:
{"error":true,"message":"Unauthorized","status":401}
This happens even when auth/account health appears good and even for --draft with no media.
Why this matters
For CLI/agent workflows, accounts:health is the preflight source of truth before publishing. If it reports healthy + canPost: true + tokenValid: true + needsReconnect: false, an AI agent or automation will reasonably attempt to publish.
When posts:create still returns 401, the CLI cannot decide whether to:
- retry,
- ask the user to reconnect,
- refresh auth,
- switch account/profile,
- or report a server-side bug.
The current output also makes automated recovery hard because the error lacks the failing layer: API key auth vs social account token vs profile/account permission vs backend publish authorization.
Related observation
A similar 401 pattern also occurred earlier with X/Twitter publishing while accounts:health showed tokenValid: true, canPost: true, needsReconnect: false, but with warning Token expired or expiring soon (auto-refresh pending). That case eventually looked like a token refresh edge case.
The Facebook case in this report is stricter: account health reports healthy and no issues, but posts:create still fails 401, including draft-only/no-media.
Proposed direction
Possible fixes or improvements:
- Make
accounts:health reflect the same authorization checks required by posts:create.
- Improve
posts:create error output to include a safe diagnostic code, e.g. API_KEY_UNAUTHORIZED, SOCIAL_TOKEN_EXPIRED, ACCOUNT_NOT_POSTABLE, PROFILE_PERMISSION_DENIED, PAGE_PERMISSION_MISSING, etc.
- If backend knows reconnect is required, return that in the CLI error.
- Consider adding a CLI preflight command or
posts:create --debug-safe mode that prints non-secret diagnostics: profile ID, target platform, account username, canPost, token status, resolved platform target, and backend error code.
Acceptance criteria
- A healthy Facebook account that reports
canPost: true can successfully create a draft or publish a post via zernio posts:create.
- If publishing is impossible,
accounts:health and/or posts:create clearly reports the actionable reason.
- The CLI does not expose secrets in error output.
Bug:
posts:createreturns 401 whileauth:checkandaccounts:healthreport valid credentials/accountSummary
zernio posts:createfails withUnauthorized/ HTTP 401 even though:zernio auth:check --prettyreports the API key is validzernio accounts:health --prettyreports the target Facebook account ishealthycanPost: true,tokenValid: true, andneedsReconnect: falsezernio media:uploadsucceeds with the same CLI/auth contextThis makes the CLI state contradictory: account health says the account is postable, but every
posts:createattempt is rejected with 401.Environment
zernio --version→0.3.0@zernio/cli0.3.0zernio-dev/zernio-climainmrgoon.info/ MrGoon)No API keys or tokens are included in this report.
Reproduction steps
Actual result:
{ "success": true, "message": "API key is valid" }Relevant target account result:
{ "platform": "facebook", "username": "mrgoon.info", "displayName": "MrGoon", "status": "healthy", "canPost": true, "tokenValid": true, "needsReconnect": false, "issues": [] }Actual result: both uploads succeeded and returned media URLs.
Actual result:
{"error":true,"message":"Unauthorized","status":401}Actual result:
{"error":true,"message":"Unauthorized","status":401}Actual result:
{"error":true,"message":"Unauthorized","status":401}Expected behavior
One of these should happen:
posts:createsucceeds because the account health endpoint says the API key and Facebook account are valid/postable; oraccounts:healthshould report the account as not postable, token invalid, missing permission, needing reconnect, or otherwise blocked; orposts:createshould return a more actionable error than a genericUnauthorized, e.g. which credential/token layer failed and whether the user must reconnect, refresh the API key, select another profile, or reauthorize page permissions.Actual behavior
posts:createreturns only:{"error":true,"message":"Unauthorized","status":401}This happens even when auth/account health appears good and even for
--draftwith no media.Why this matters
For CLI/agent workflows,
accounts:healthis the preflight source of truth before publishing. If it reportshealthy+canPost: true+tokenValid: true+needsReconnect: false, an AI agent or automation will reasonably attempt to publish.When
posts:createstill returns 401, the CLI cannot decide whether to:The current output also makes automated recovery hard because the error lacks the failing layer: API key auth vs social account token vs profile/account permission vs backend publish authorization.
Related observation
A similar 401 pattern also occurred earlier with X/Twitter publishing while
accounts:healthshowedtokenValid: true,canPost: true,needsReconnect: false, but with warningToken expired or expiring soon (auto-refresh pending). That case eventually looked like a token refresh edge case.The Facebook case in this report is stricter: account health reports
healthyand no issues, butposts:createstill fails 401, including draft-only/no-media.Proposed direction
Possible fixes or improvements:
accounts:healthreflect the same authorization checks required byposts:create.posts:createerror output to include a safe diagnostic code, e.g.API_KEY_UNAUTHORIZED,SOCIAL_TOKEN_EXPIRED,ACCOUNT_NOT_POSTABLE,PROFILE_PERMISSION_DENIED,PAGE_PERMISSION_MISSING, etc.posts:create --debug-safemode that prints non-secret diagnostics: profile ID, target platform, account username, canPost, token status, resolved platform target, and backend error code.Acceptance criteria
canPost: truecan successfully create a draft or publish a post viazernio posts:create.accounts:healthand/orposts:createclearly reports the actionable reason.