← Commit history

1.9.144: #49 bind error:null + good-urn-continues

John Lauer ·5a19edc3cf ·1mo ago ·parent 905296c
6 files changed +42−11
BRIDGE_VERSION+1−1
@@ -1 +1 @@-1.9.143\ No newline at end of file+1.9.144\ No newline at end of file
adom-bridge-fusion-manifest.json+4−4
@@ -1,10 +1,10 @@ {   "manifest_version": 1,   "name": "fusion360",-  "version": "1.9.143",-  "url": "https://wiki.adom.inc/download/adom/fusion-bridge/1.9.143/adom-bridge-fusion-v1.9.143.zip",-  "sha256": "30f0804b30fd31e7aabce8e7e392289d0134e32446483e14fef62f5a531c176c",-  "size": 477125,+  "version": "1.9.144",+  "url": "https://wiki.adom.inc/download/adom/fusion-bridge/1.9.144/adom-bridge-fusion-v1.9.144.zip",+  "sha256": "a837068a86331208532d08ac2e286afac8908fdccd99a4fecfd3aef75edde888",+  "size": 477909,   "verbPrefixes": [     "fusion_"   ],
bridge.json+1−1
@@ -2,7 +2,7 @@   "manifest_version": 1,   "name": "fusion360",   "displayName": "Autodesk Fusion 360",-  "version": "1.9.143",+  "version": "1.9.144",   "description": "Drive Autodesk Fusion 360 from the cloud: launch Fusion, electronics board layout, design rules, exports (STEP/IGES/STL/3MF/USDZ/OBJ/DXF/DWG/Gerbers/BOM/CPL), fast APS server-indexed cloud search plus browse/recent/file-info/versions, cloud file download/upload and folder creation, and in-app parametric modeling (fusion_run_modeling_script). Never-charge: APS calls are capped to the free tier.",   "homepage": "https://wiki.adom.inc/adom/fusion-bridge",   "author": "Adom Inc.",
package.json+1−1
@@ -1,6 +1,6 @@ {   "slug": "fusion-bridge",-  "version": "1.9.165",+  "version": "1.9.166",   "type": "app",   "description": "This package installs the bridge's SKILLS into your container so your AI knows how to drive it; Adom Bridge loads the bridge runtime itself from the release zip.",   "dependencies": {
page.json+1−1
@@ -1,6 +1,6 @@ {   "slug": "fusion-bridge",-  "version": "1.9.165",+  "version": "1.9.166",   "type": "app",   "description": "This package installs the bridge's SKILLS into your container so your AI knows how to drive it; Adom Bridge loads the bridge runtime itself from the release zip.",   "dependencies": {
server.py+34−3
@@ -8651,9 +8651,28 @@ def _orchestrate_bind_library_3d(args: dict) -> dict:         return {"success": False, "error": "binding write failed: %s" % e, "wip_urn": urn}     _t.sleep(1)     reopened = _orchestrate_open_lbr({"filePath": lbr_path})-    return {"success": bool(reopened.get("success")), "wip_urn": urn,+    _reopen_ok = bool(reopened.get("success"))+    # THE BIND ITSELF IS DONE once the urn is minted AND written to the .lbr on disk+    # (#49 / #47 failure-mode-3, John 2026-08-23). The re-open here is only a refresh so the+    # prove stage can screenshot the 3D - its failure must NEVER (a) present as a bind failure+    # with error:null, nor (b) discard a real, minted, PERSISTED urn and abort the chain. Two+    # rules from that report: never return error:null on a failure, and a good urn lets the+    # chain continue. So: success rides on the urn+write (the actual binding work), and the+    # re-open is reported separately with its reason surfaced.+    if not _reopen_ok:+        _why = str(reopened.get("error") or reopened.get("_hint")+                   or "library re-open returned success:false with no detail (open_lbr)")[:220]+        return {"success": True, "wip_urn": urn, "libraryPath": lbr_path,+                "deviceset": deviceset, "bound": True, "reopened": False,+                "reopenError": _why,+                "_hint": ("Binding minted (%s) and WRITTEN to the .lbr - the bind is real and "+                          "persisted. Re-opening the library into Fusion failed (reopenError "+                          "above); the prove stage opens the library itself, so the chain "+                          "continues. If prove's 3D frame is missing, the library just needs a "+                          "clean re-open once Fusion is idle." % urn)}+    return {"success": True, "wip_urn": urn,             "libraryPath": lbr_path, "deviceset": deviceset,-            "bound": True, "reopened": bool(reopened.get("success")),+            "bound": True, "reopened": True,             "_hint": ("Library re-opened WITH the 3D binding. The Content Manager's 3D preview "                       "resolves after Autodesk's thumbnail service catches up (~2-3 min for a "                       "fresh mint) - EDIT %s.dev then screenshot to verify the render." % deviceset)}@@ -10361,8 +10380,20 @@ def _handle_create_library(fusion_info: dict, args: dict) -> dict:                 bind = dispatch_command("bind_library_3d",                                         {"libraryPath": target_lbr, "stepPath": step_p})                 state["bind"] = {k: bind.get(k) for k in-                                 ("success", "error", "wip_urn")}+                                 ("success", "error", "wip_urn", "reopened",+                                  "reopenError")}                 if not bind.get("success"):+                    # NEVER surface a failure with error:null (#49, John 2026-08-23). If the+                    # bind handler somehow returns no reason, synthesize one from whatever it+                    # did carry so the caller always sees WHY, never a silent rejection next+                    # to a real urn.+                    if not state["bind"].get("error"):+                        _u = state["bind"].get("wip_urn")+                        state["bind"]["error"] = (+                            ("bind reported failure but gave no reason; a urn WAS minted (%s) "+                             "- likely a post-mint step (library re-open / verify) failed "+                             "silently" % _u) if _u else+                            "bind failed and returned no reason and no urn")                     state.update(stage="failed", success=False); _save(); return                 _leave("bind")             _enter("proving (four evidence frames)")