{"record":{"id":"0e97588410b99210","repo":"we-promise/sure","slug":"your-account-is-not-authorized-to-use-the-external","errorCode":null,"errorMessage":"Your account is not authorized to use the external assistant.","messagePattern":"Your account is not authorized to use the external assistant\\.","errorType":"exception","errorClass":"Assistant::Error","httpStatus":null,"severity":"error","filePath":"app/models/assistant/external.rb","lineNumber":46,"sourceCode":"        url: ENV[\"EXTERNAL_ASSISTANT_URL\"].presence || Setting.external_assistant_url.presence,\n        token: ENV[\"EXTERNAL_ASSISTANT_TOKEN\"].presence || Setting.external_assistant_token.presence,\n        agent_id: ENV[\"EXTERNAL_ASSISTANT_AGENT_ID\"].presence || Setting.external_assistant_agent_id.presence || \"main\",\n        session_key: ENV.fetch(\"EXTERNAL_ASSISTANT_SESSION_KEY\", \"agent:main:main\")\n      )\n    end\n  end\n\n  def respond_to(message, assistant_message: nil)\n    response_completed = false\n    assistant_message ||= AssistantMessage.new(chat: chat, content: \"\", ai_model: \"external-agent\")\n\n    unless self.class.configured?\n      raise Assistant::Error,\n        \"External assistant is not configured. Set the URL and token in Settings > Self-Hosting or via environment variables.\"\n    end\n\n    unless self.class.allowed_user?(chat.user)\n      raise Assistant::Error, \"Your account is not authorized to use the external assistant.\"\n    end\n\n    client = build_client\n    messages = build_conversation_messages\n\n    model = client.chat(\n      messages: messages,\n      user: \"sure-family-#{chat.user.family_id}\"\n    ) do |text|\n      assistant_message.append_text!(text)\n    end\n\n    if assistant_message.content.blank?\n      raise Assistant::Error, \"External assistant returned an empty response.\"\n    end\n\n    response_completed = true\n    assistant_message.update!(ai_model: model) if model.present?","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/we-promise/sure/blob/e69894adb92547273377398c15f45c979cd9416a/app/models/assistant/external.rb#L28-L64","documentation":"After passing the configured? gate, Assistant::External#respond_to checks self.class.allowed_user?(chat.user) before building the client. When the user isn't on the external assistant's allowlist (the class defines which users may use it — typically admin/restricted-demo policy), it raises Assistant::Error(\"Your account is not authorized to use the external assistant.\"). This is an application-level authorization decision, not an HTTP 401 from the remote agent — no network request has been made yet when this raises.","triggerScenarios":"A regular (non-permitted) family member selecting the external agent model in the assistant UI; demo deployments where only specific accounts may use the shared agent; a user record that no longer satisfies allowed_user? after a role change (member demoted, admin flag removed) while their existing chat still targets the external model; SSO/user rename that changed whatever identity key allowed_user? matches on.","commonSituations":"Rolling the external agent out to admins first and members finding the entry point anyway; leftover external-model chats after a user's role changed; multi-family installs with per-user gating; testers using a scratch account that was never allowlisted.","solutions":["Confirm with the operator who is allowed: check Assistant::External.allowed_user?(user) in console to see the policy verdict for that exact user","Switch the chat to a permitted assistant/model (the built-in LLM assistant) if your account isn't intended to use the external agent","If you ARE meant to have access, have an admin adjust whatever allowed_user? checks (role/flag) for your account","Close or re-model old chats that still point at 'external-agent' after your role changed — they will keep raising on every send"],"exampleFix":"# before\nAssistant::External.allowed_user?(chat.user) # => false\nchat.messages.create!(content: \"hi\", ai_model: \"external-agent\")\n# => Assistant::Error: Your account is not authorized to use the external assistant.\n\n# after\nif Assistant::External.allowed_user?(chat.user)\n  Assistant::External.new(chat).respond_to(message)\nelse\n  message.update!(ai_model: \"gpt-4o\") # or another permitted model\n  Assistant::Builtin.new(chat).respond_to(message)\nend","handlingStrategy":"validation","validationCode":"# Gate the model choice per user before sending\nif message.ai_model == \"external-agent\" && !Assistant::External.allowed_user?(chat.user)\n  # block early with a clear message; offer permitted models instead\n  raise Unauthorized, \"not allowed for this user\"\nend","typeGuard":"def may_use_external_assistant?(user)\n  Assistant::External.allowed_user?(user)\nend","tryCatchPattern":"rescue Assistant::Error => e\n  if e.message.include?(\"not authorized\")\n    # authorization policy: do not retry; offer model switch\n    chat.add_error(e)\n    message.update!(ai_model: fallback_model)\n  else\n    raise\n  end\nend","preventionTips":["Hide the external-agent option from users who fail allowed_user?","Re-check authorization when users' roles change; retire their external-model chats","Test allowed_user? for each role in your policy's test suite","Communicate the allowlist policy to the family/team so users know whom to ask"],"tags":["rails","assistant","authorization","access-control"],"backgroundTag":"authorization-denied","analyzedSha":"e69894adb92547273377398c15f45c979cd9416a","analyzedAt":"2026-08-21T18:22:41.165Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}