{"record":{"id":"6482285ebda33967","repo":"jackwener/OpenCLI","slug":"instagram-follow-returned-no-success-evidence","errorCode":null,"errorMessage":"Instagram follow returned no success evidence","messagePattern":"Instagram follow returned no success evidence","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"clis/instagram/follow.js","lineNumber":41,"sourceCode":"  const opts = { credentials: 'include', headers };\n\n  ${buildResolveInstagramUserIdJs()}\n\n  const csrf = document.cookie.match(/csrftoken=([^;]+)/)?.[1] || '';\n  const r2 = await fetch('https://www.instagram.com/api/v1/friendships/create/' + userId + '/', {\n    method: 'POST',\n    credentials: 'include',\n    headers: { ...headers, 'X-CSRFToken': csrf, 'Content-Type': 'application/x-www-form-urlencoded' },\n  });\n  if (!r2.ok) throw new Error('Failed to follow: HTTP ' + r2.status);\n  let d2;\n  try {\n    d2 = await r2.json();\n  } catch {\n    throw new Error('Instagram follow returned invalid JSON');\n  }\n  if (!d2 || typeof d2 !== 'object' || d2.status !== 'ok' || !d2.friendship_status || typeof d2.friendship_status !== 'object') {\n    throw new Error('Instagram follow returned no success evidence');\n  }\n  const status = d2.friendship_status.following ? 'Following' : d2.friendship_status.outgoing_request ? 'Request sent' : '';\n  if (!status) throw new Error('Instagram follow returned no success evidence');\n  return [{ status, username }];\n})()\n` },\n    ],\n});\n","sourceCodeStart":23,"sourceCodeEnd":50,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/instagram/follow.js#L23-L50","documentation":"After successfully parsing the response JSON from /api/v1/friendships/create/, the CLI validates that the payload proves the follow succeeded: it must be an object with status === 'ok', a friendship_status object. If the JSON parses but lacks that shape (e.g. status 'fail' with a message field), this error is thrown. It indicates Instagram rejected or did not confirm the follow despite returning HTTP 200.","triggerScenarios":"POST to friendships/create returns JSON that is not an object, has status !== 'ok', or omits/mistypes friendship_status — e.g. {status:'fail', message:'Please wait a few minutes...'} from rate limiting or an action block.","commonSituations":"Account hit action-block/temporary follow limit; private account where the request silently didn't register; Instagram API contract changed and renamed friendship_status; response is a spammed-likes/bot-detection error envelope.","solutions":["Read the response's message/status fields (log d2 in a wrapper) to see Instagram's stated reason (rate limit, action block).","Wait and retry later if the account is action-blocked; follow limits reset over time.","Re-login to refresh session/cookies if Instagram is returning degraded responses.","Check the friendship status separately (GET /api/v1/friendships/show/<id>/) to see if the follow actually took effect."],"exampleFix":"// before\nconst res = await cli.follow(username);\n// after\ntry {\n  const res = await cli.follow(username);\n} catch (e) {\n  if (String(e.message).includes('no success evidence')) {\n    // inspect raw API response / check action block before retrying\n  }\n}","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"function isFollowSuccess(d) {\n  return !!d && typeof d === 'object' && d.status === 'ok' &&\n    !!d.friendship_status && typeof d.friendship_status === 'object' &&\n    (d.friendship_status.following === true || d.friendship_status.outgoing_request === true);\n}\n// usage: if (!isFollowSuccess(d2)) { /* surface d2.message before retrying */ }","tryCatchPattern":"try {\n  const res = await followUser(username);\n} catch (e) {\n  if (String(e.message).includes('no success evidence')) {\n    // check action-block: inspect raw API message, back off before retry\n  } else throw e;\n}","preventionTips":["Respect follow-rate limits; space out write actions to avoid action blocks.","Capture and log the full response envelope (status/message) for diagnosis.","Verify friendship state independently via friendships/show after failures.","Handle private accounts: expect outgoing_request semantics."],"tags":["instagram","api-contract","rate-limit","response-validation"],"backgroundTag":"schema-validation-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}