solarOSsolarOS Docs

This page is built from strings that actually appear in the product: each entry quotes the exact text so you can search for it. If you hit a message not listed here, check the generated error codes reference for API errors, or ask in your team's support channel.

App messages

"QuickBooks is not connected for this organization."

Shown on an invoice's QuickBooks section (invoice-quickbooks-section.tsx) when the organization hasn't completed the QuickBooks OAuth connection. Go to Settings → Integrations → QuickBooks and connect the account before syncing that invoice.

"QuickBooks integration is not connected"

Thrown from apps/web/src/lib/quickbooks/invoice-pdf.ts when generating an invoice PDF that needs QuickBooks data and the org isn't connected. Same fix as above: connect QuickBooks first.

"Provider has not connected their Stripe account"

Returned from the checkout API (/api/checkout/[quoteId]) when a customer tries to pay a quote and the contractor organization hasn't connected Stripe. This blocks the customer's payment entirely; the organization needs to complete Stripe Connect onboarding before sending payable quotes.

"Not connected" (integration badge)

The Installed tab's default badge for any catalog integration without a live connection record. Note: some catalog entries are marked platformOnly (visible only to platform admins, not wired end-to-end for org users yet); those will always read "Not connected" for a regular org user, which isn't a bug to chase; it means the integration isn't available to your organization yet.

TODO(owner, likely integrations): confirm which catalog entries are currently platformOnly (see apps/web/src/lib/integrations/catalog.ts) so this page can name them instead of leaving org admins guessing why a listed integration won't connect.

"Permission denied" / "Access denied" / "Unauthorized"

Generic 403/401 messaging shown across the app and returned by internal API routes when the signed-in user's role lacks the permission the action requires. Ask an Owner or Admin to check your role against the permissions matrix.

"No permissions have been seeded yet."

Empty state in the custom role permission-matrix editor (apps/web/src/components/settings/people/permission-matrix.tsx), shown when the permission catalog hasn't been seeded for that organization.

TODO(owner, likely engineering): confirm what triggers this state in practice (new organization before a seed job runs? a specific migration gap?) and what an Owner should actually do when they see it: the component only renders the empty state, it doesn't explain the fix.

"All monitoring devices are offline" / "Some devices are not reporting data"

Customer-facing titles from determineHealthStatus in apps/web/src/lib/monitoring/system-health.ts; see Device health for how these are computed. "All ... offline" means every device at the property is DISCONNECTED/ERROR; "Some ... not reporting" means some but not all are. Neither is necessarily urgent by itself: check the property's active alerts for severity before treating it as an outage.

Data freshness questions

"Why is my data 15–60 minutes old?" Monitoring telemetry syncs from Texture on an hourly cron (monitoring-texture-sync-cron, apps/web/src/inngest/monitoring/texture-sync.ts), not in real time. See Data freshness for the full explanation and TODO on confirming the exact bound.

"Why doesn't the health color match what I'd expect?" Health status (green/amber/red) is computed from alerts + connection status, not stored as a field: it can change the moment an alert opens or closes even if no device state changed. See Device health.

Org API errors

Every Org API error follows the envelope in Errors: error.code, error.message, optional error.details. Two worth calling out because they're easy to misdiagnose as bugs:

  • 429 RATE_LIMITED: message is literally Rate limit exceeded. Retry after <n> seconds. (apps/web/src/lib/org-api/lifecycle.ts). Respect the Retry-After header; don't hammer retries.
  • 409 IDEMPOTENCY_CONFLICT: you reused an Idempotency-Key with a different request body. Generate a new key per logical operation instead of reusing one across different payloads. See Errors for the full safe-retry explanation.

For the full list of codes and their HTTP statuses, see the generated error codes reference.

Was this page helpful?

On this page