05.14.2026

Today’s release includes the following updates:

bugfix

  • Fixed several command-related issues:
    • Commands added to a note from a chart button could occasionally disappear from the note body.
    • Deleting a command no longer leaves the note out of date until refresh.
    • When post-processing events after a command was committed or marked enter-in-error failed, the command appeared committed/EIE in the UI but related records could end up out of sync. The status change is now rolled back if any post-processing records fails.
    • Commands could move to “in review” even when required fields were missing or invalid; the move is now blocked until the validation errors are resolved.
    • Prescribers who already had an SPI number on file were still being prompted to add one before reviewing an adjust-prescription command.
    • Questionnaire comments can be opened on locked or signed notes for multiple-choice fields that accept comments.
    • Goals could not be updated when the start date field had been cleared.
  • The schedule view was not honoring the configured order of providers; providers now appear in their assigned schedule-column order.
  • Fixed crashes in the Day and Week views in the schedule that could occur when an appointment was created, edited, or canceled in real time — most commonly right after switching dates or location filters.
  • The Letter author dropdown now searches the full staff directory as you type, so customers with more than 350 active staff members can find and select any provider (previously the dropdown showed only the first set of providers).
  • CCDA exports for patients without an assigned team lead now return a clear error explaining the missing team lead, instead of a generic server error, so integrations know to correct the patient record rather than retry the export.
  • Resolved a source of app-wide slowness during Health Gorilla lab report ingestion that was tying up the database while Canvas waits on it.
  • Fixed a bug related to Timed out after 60s waiting for namespace '<namespace>' to be created by the schema manager errors during plugin install, which would leave the plugin disabled and require a manual re-enable to recover.

ui

  • Redesigned the diagnostic imaging requisition: provider name, license, and NPI now appear in a dedicated Ordering Provider block at the top; a medical-necessity certification, an electronically-signed attestation with a timezone-stamped date, and an order-validity statement now appear at the bottom.

sdk

Data

  • Added a LabTest relationship to LabValue in the SDK data module, enabling plugins to associate lab values with their corresponding tests. See the LabTest reference and Ordered vs. result tests.
  • Staff member signatures are now accessible via the SDK data module. Read more.

Events

  • Plugins can now respond to a new SDK event, PATIENT_PAYMENT_PROCESSED, triggered when a patient payment is processed. Read more.

Config

  • Plugins can now read the instance’s configured time zone via self.environment["INSTALLATION_TIME_ZONE"] (an IANA name like America/Los_Angeles), enabling accurate local-time rendering in plugin output. Read more.
  • Added a --disable flag to canvas install so plugins can be installed in a disabled state via the CLI (defaults to enabled). (requires Canvas CLI 0.143.0 or newer) Read more.
  • New variables schema for plugin configuration declared in CANVAS_MANIFEST.json. (requires Canvas CLI 0.147.0 or newer)
    • Manifest schema: CANVAS_MANIFEST.json now accepts a variables array of {name, sensitive} objects in place of the flat secrets string array, distinguishing sensitive secrets (such as API tokens) from non-sensitive configuration values (such as log levels or feature flags). The legacy secrets field still works but emits a deprecation warning during canvas validate-manifest, and is internally mapped to variables entries with sensitive: false. Read more.
    • CLI: A canvas install --variable KEY=value flag is available alongside --secret for non-sensitive values. canvas config list now renders each variable as [set] or [not set], with a (sensitive) annotation for sensitive variables — values themselves are never displayed. Read more.
    • Settings UI: Sensitive variables display as SENSITIVE in Settings — leave the field blank to keep the existing value, or submit a new value to overwrite. Non-sensitive variables remain editable inline with their current value visible.
    • Plugin runtime: Handler code reading values via self.secrets["KEY"] is unchanged — sensitive and non-sensitive values land in the same dictionary. Migrating a plugin from secrets: to variables: requires no handler code changes.
    • ⚠️ Migration caveat: Existing plugin secrets and any values configured via the legacy secrets: array default to non-sensitive in this release — they will appear in plain text in the Admin UI until the owning plugin is migrated to the variables schema with sensitive: true and re-installed.