Skip to content

bug: Scratchから読み込むが特定 URL で失敗する報告 (要追加情報) #573

@takaokouji

Description

@takaokouji

概要

「Scratchから読み込む」機能で、過去開けた URL でも今は開けないというフィードバックがあった。proxy https://api.smalruby.app/scratch-api-proxy/projects/:id 経由で project_token を取得 → https://projects.scratch.mit.edu/:id?token=... で本体ロードという流れだが、特定の条件で失敗する可能性がある。

ユーザーフィードバック (Discussion smalruby/smalruby3-develop#81):

Scratchから読み込むが正しく機能していない。前は開けたURLでも今は開けない

再現確認結果 (2026-04-29 時点)

私が手元で試した範囲では再現せず。ユーザーが具体的にどの URL で失敗しているか追加情報が必要

試した条件

すべて smalruby.app 本番環境、Chrome/Playwright で 1280x800 viewport。

プロジェクト ID 状態 proxy /scratch-api-proxy/projects/:id projects.scratch.mit.edu エディタロード
1209008277 (demo-extension-translate3, Stage のみ + translate/text2speech) 公開済み 200 OK, project_token 取得 200 OK ✅ Stage + 8 blocks
108317385 (Winter Squirrel, 2 targets, 8 costumes) 公開済み 200 OK 200 OK ✅ Stage + Squirrel + 75 blocks
9999999999 (存在しない) NotFound 200 OK + body {"code":"NotFound","message":""} 403 (token 無し) ❌ アラート「プロジェクトURLの読み込みに失敗しました。」

proxy / Scratch API の動作確認 (curl)

$ curl -i 'https://api.smalruby.app/scratch-api-proxy/projects/1209008277'
HTTP/2 200
access-control-allow-origin: https://smalruby.app
access-control-allow-headers: Content-Type
access-control-allow-methods: OPTIONS,GET
{"id":1209008277,...,"project_token":"1777437935_..."}

$ curl -i 'https://api.smalruby.app/scratch-api-proxy/projects/9999999999'
HTTP/2 200    # ← 重要: 404 でなく 200 を返す
{"code":"NotFound","message":""}

CORS ヘッダ access-control-allow-origin: https://smalruby.app は正しく設定されている。Scratch 側 https://api.scratch.mit.edu/projects/:id も外部から fetch すれば普通に 200 を返す (CORS は restrict されているが proxy 経由で問題なし)。

仮説と懸念点

仮説1: 特定タイプのプロジェクトで失敗する可能性

  • 共有解除/非公開化されたプロジェクト: proxy が 200 + {"code":"NotFound"} を返し、project_token が undefined のまま projects.scratch.mit.edu にリクエスト → 403 でロード失敗 (アラートは出る)。「前は開けたが今は開けない」の典型パターン。ユーザーが共有解除されたプロジェクトを開こうとしている場合は、これが原因の可能性高い
  • scratch.mit.edu 側で削除されたプロジェクト: 上と同様。
  • 巨大プロジェクト: project_token は取れるが asset 取得タイムアウト。
  • クラウド変数を使うプロジェクト: プレイヤーモードでないとロードしないかもしれない (要確認)。
  • Scratch 1.x / 2.0 形式 (.sb / .sb2): 互換性の問題で失敗することがある。
  • 特定の拡張機能 (Music, Translate, TextToSpeech): 拡張ロード失敗の可能性。

仮説2: proxy / Scratch 側のエラーレスポンス処理が不十分

packages/scratch-gui/src/lib/url-loader-hoc.jsx の処理:

fetch(options.uri, ...)
    .then(response => {
        if (!response.ok) {
            throw new Error(`HTTP ${response.status}`);
        }
        return response.json();
    })
    .then(data => {
        const projectToken = data.project_token;  // ← undefined になり得る
        const storage = this.props.storage;
        storage.setProjectToken?.(projectToken);  // ← undefined を渡してしまう
        return storage.scratchStorage.load(...);
    })

proxy が 200 + {"code":"NotFound"} を返したケースで、data.project_token が undefined であることをチェックしていない。エラーハンドリングは最終的に動作するが (アラートは出る)、エラーメッセージが具体的ではない (「プロジェクトURLの読み込みに失敗しました。」)。

仮説3: ユーザーが Scratch にログインしないと見えないプロジェクトを開こうとしている

未公開・非公開のプロジェクトは api.scratch.mit.edu 自身が NotFound を返す。これは仕様。

必要な追加情報

ユーザーに以下を確認したい:

  1. 失敗する具体的な URL (例: https://scratch.mit.edu/projects/12345678/)
  2. そのプロジェクトが今も Scratch 公式サイトで普通に閲覧できるか (https://scratch.mit.edu/projects/12345678/ を直接ブラウザで開けるか)
  3. 「前は開けた」のは何時頃か — 数日前か数か月前か
  4. エラー表示 — 「プロジェクトURLの読み込みに失敗しました。」というアラートが出ているか、それとも無反応か

関連ファイル

  • packages/scratch-gui/src/lib/url-loader-hoc.jsx — URL loader 実装
  • packages/scratch-gui/src/lib/url-parser.js — URL → projectId 抽出
  • packages/scratch-gui/src/components/url-loader-modal/ — UI
  • proxy: infra/ 配下にはなく、別管理 (api.smalruby.app/scratch-api-proxy/)

改善案 (要追加調査後に対応)

  1. proxy のレスポンス検証強化data.project_token が undefined の場合に明確なエラーをスロー
  2. エラーメッセージの具体化 — 「プロジェクトが見つかりません/非公開です」「proxy が応答しません」など原因別に
  3. proxy 側の対応 — NotFound のとき HTTP 404 を返す (現状 200) と扱いやすい

関連 Discussion

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions