Skip to content

[Bug] Image not rendering due to mobx-state-tree action error in ImageEntity.js #9315

@KEMSHlM

Description

@KEMSHlM

Describe the bug
Images are not rendering in the labeling interface. Network requests for image data succeed (200 OK), but the <img> element is not generated. The browser console shows
mobx-state-tree error when the setError method attempts to modify state outside of an action context.

Console error:
Uncaught (in promise) Error: [mobx-state-tree] Cannot modify 'ImageEntity@/annotationStore/annotations/0/root/children/0/imageEntities/0(id: image#0@C17cO)', the object i protected and can only be modified by using an action.
at ImageEntity.js:238:20

To Reproduce

  1. Go to a project with images stored in AWS S3
  2. Click on a task to open the labeling interface
  3. Observe that the image area is blank
  4. Open browser DevTools → Console tab
  5. See the mobx-state-tree error

Expected behavior
The image should be displayed in the labeling interface. If image loading fails, an error message should be shown without breaking the entire rendering process.

Screenshots
Image

The .lsf-image container only contains a 1px canvas overlay, with no <img> element:

<div class="lsf-image" style="width: 100%; height: auto;">
  <canvas class="overlay--kj18y" style="width: 1px; height: 1px; ..."></canvas>
</div>

Environment (please complete the following information):

  • OS: N/A (HumanSignal Cloud)
  • Label Studio Version: HumanSignal Cloud (app.heartex.com) - latest as of 2026-02-03
  • Storage: AWS S3

Additional context

Root Cause Identified

cc @bmartel

The bug was introduced in #6930 (merged 2025-01-27).

In ImageEntity.js, the img.onerror callback modifies mobx-state-tree state outside of an action context:

img.onerror = () => {
    self.setError(true);        // ← This might be outside action context
    self.setDownloading(false);
    resolve();
};

Since onerror is an asynchronous callback, it may execute outside the original preload() action's context. In mobx-state-tree, modifying state outside of an action throws an exception, which could be interrupting the image rendering process.

Possible Fix (suggested by Claude)

Claude suggested that wrapping the state modifications in runInAction might resolve the issue:

import { runInAction } from "mobx";

img.onerror = () => {
    runInAction(() => {
      self.setError(true);
      self.setDownloading(false);
    });
    resolve();
};

I'm not entirely sure if this is the correct approach, so please let me know if there's a better solution.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions