workers.api.error.invalid_script_config error 10202

Hi, I'm trying to PATCH script settings to add the D1 binding of a dynamically created D1 database (this, works correctly), but I have this weird error that doesn't give much informations. If I only send a simple settings object with my new binding, it's works, but I'm losing old previous bindings access, so I'm trying first to GET all settings, and to PATCH the same settings object with just pushing in the settings.bindings the new binding. This error is returned. I've also tried to only return a new settings objects that only contains all theses bindings, same error too. Any help will be appreciated! 🙂
33 Replies
kian
kian•13mo ago
Do you have an example of the FormData/JSON you're sending to the API? You can see how Wrangler does it here: https://github.com/cloudflare/workers-sdk/blob/dd270d0065159150ff318f2f06607ddecba6ee9b/packages/wrangler/src/secret/index.ts#L401-L460
GuillaumeLakano
GuillaumeLakanoOP•13mo ago
Thank you for your time & help this is how I GET the settings (with success): const script = d1-bindings-${env.ENV.toLowerCase()} let respSettings = await fetch(https://api.cloudflare.com/client/v4/accounts/${app.secrets.CF_ACCOUNT_ID}/workers/scripts/${script}/settings`, { method: 'GET', headers: { 'Authorization': Bearer ${app.secrets.CF_API_TOKEN}, 'Content-Type': 'application/json', } , }) respSettings = await respSettings.json() and here how I PATCH it: const newBinding = { id: uuid, name: C_${uuid.replaceAll('-', '_')}, type: 'd1' } const settings = respSettings.result settings.bindings.push(newBinding) const body = new FormData() body.set('settings', JSON.stringify(settings)) let respAssign = await fetch(https://api.cloudflare.com/client/v4/accounts/${app.secrets.CF_ACCOUNT_ID}/workers/scripts/${script}/settings, { method: 'PATCH', headers: { 'Authorization': Bearer ${app.secrets.CF_API_TOKEN}, } , body, }) respAssign = await respAssign.json()`
kian
kian•13mo ago
Can you log settings and see what that looks like?
GuillaumeLakano
GuillaumeLakanoOP•13mo ago
The PATCH only works if I don't keep the old content of the bindings settings
kian
kian•13mo ago
After you push the newBinding
GuillaumeLakano
GuillaumeLakanoOP•13mo ago
now with the CF outage, I can't, but from my memory, everything was correctly injected, there is also secrets / env, inside, and one weird thing is the GET return a different bindings format that the documentation request it for PATCH The key « database_id » is named database_id on the GET, but we should use « id » rather than « database_id » for PATCH ( it's not consistent so ), but I've also tried both
kian
kian•13mo ago
At a glance
GuillaumeLakano
GuillaumeLakanoOP•13mo ago
can you confirm I need to GET all the settings, inject a new bindings in the array and keep all previous settings + previous bindings as before ?
kian
kian•13mo ago
You might want to change body.set('settings', JSON.stringify(settings)) to body.set('settings', JSON.stringify(settings.bindings)) You can provide just bindings, but it cannot be a partial list of bindings. Or rather, body("settings", JSON.stringify({ bindings: settings.bindings }));
GuillaumeLakano
GuillaumeLakanoOP•13mo ago
if I do that, this will do something like: body.set('settings', JSON.stringify([ { id: ..., name: ..., type: 'd1' }, ... ]) Seems to not respect what the documentation describe: https://developers.cloudflare.com/api/operations/worker-script-patch-settings
Cloudflare API Documentation
Interact with Cloudflare's products and services via the Cloudflare API
GuillaumeLakano
GuillaumeLakanoOP•13mo ago
my « settings » var contains something like : { bindings: [...], limits: { ... }, ... }, seems to be the good format, isn't it ?
kian
kian•13mo ago
They do data.set("settings", JSON.stringify({ bindings })); but that's because the parameter name is bindings, so it ends up becoming bindings: [...] - in your case, it'd be JSON.stringify({ bindings: settings.bindings })
GuillaumeLakano
GuillaumeLakanoOP•13mo ago
Ok, I'll try that after the end of the outage 🙂 this will keep all the others settings of the script ? ( cpu_ms, compatibility_date, .... ) ?
kian
kian•13mo ago
It should, since it's a PATCH. It's just a caveat of the bindings field specifically. i.e you could send just compatibility_date - but not just bindings: [{newbinding}] - that's my understanding I haven't tested it, it's a new-ish API
GuillaumeLakano
GuillaumeLakanoOP•13mo ago
ok, I'll let you known, thank you so much for your help! BTW, could be really cool to permit to PATCH arrays (like bindings) without needed first to do an API GET request to manage the complete array list. If we have 2 creations of D1 database at the same time, we have a risk to loose a binding ( not atomic ) oh and sorry, a last question, do you known if there is an error in the PATCH documentation about the bindings object content, because they request a key named « id » for D1 bindings, but on a GET API, the object key is not named « id » but « database_id » So I've try both each time, but could be useful to known the good naming ^^
kian
kian•13mo ago
So there's id in the documentation but the actual API request returns database_id?
GuillaumeLakano
GuillaumeLakanoOP•13mo ago
exactly
kian
kian•13mo ago
meowthinking don't suppose you know about this, are they treated as aliases for one another? Wrangler uses id in the upload request
GuillaumeLakano
GuillaumeLakanoOP•13mo ago
it's may be why when I've PATCHed this failed, may be I also need to rename all previous bindings objects received from GET, to rename the object key from « database_id » to « id »
kian
kian•13mo ago
Since you said it worked with just the new binding, but not the existing ones, did the existing ones still have database_id in them?
GuillaumeLakano
GuillaumeLakanoOP•13mo ago
to be precise, this seems to works because I didn't received error, and then couldn't connect to any other DB that was previously associated (bindings declared from the wrangler.toml ) I presume the new bindings have been added but can't have the proof of that (because no more access to SECRETS/ENV/important others bindings), but at least the settings have been updated, may be without any bindings at all. It's only works if I put only my new bindings in the array (without old ones) A good idea to check if it's really success, should be to do after a new API GET to read the new patched Settings, I'll do this test ( with the outage, I can't upload any scripts )
kian
kian•13mo ago
I suspect the error comes from database_id in the existing bindings There might be other bindings which have the wrong keys too
GuillaumeLakano
GuillaumeLakanoOP•13mo ago
yep it's a good guess, but this also means it's not consistent between the different API calls ( PATCH / GET )
kian
kian•13mo ago
If that's the case, then we'd just try and get the GET calls fixed.
GuillaumeLakano
GuillaumeLakanoOP•13mo ago
I'll try to rename each keys name « database_id » => « id » and let you known
kian
kian•13mo ago
id is definitely correct, as Wrangler and the API have used that forever.
Max (@rozenmd)
Max (@rozenmd)•13mo ago
CC @elithrar fyi, some inconsistency between API call methods for what we call database_id in bindings
kian
kian•13mo ago
Thanks Max!
GuillaumeLakano
GuillaumeLakanoOP•13mo ago
BTW, it's weird because the BINDING can't be used directly the binding successfully updated, even after a await of 10 seconds inside my worker. I suppose there is a kind of cache somewhere or to do reset of « env » may be ? I don't known how to refresh the bindings to execute all the CREATE TABLE in the same time. I could may be use the API to send SQL requests, but the API doesn't support batch requests, and I have ~40 create table to do
Max (@rozenmd)
Max (@rozenmd)•13mo ago
pretty sure updating bindings results in the worker being redeployed, so you're probably running into provisioner lag we need to make this a better experience
GuillaumeLakano
GuillaumeLakanoOP•13mo ago
I'll try with a waiting time of 30 seconds ( await a promise setTimeout of 1s, then try again to find the env.NEW_BINDING and continue until 30s ) I've done it with 10 seconds, and in the same laps of time, I saw the binding attached in the dashboard ( in Worker => Settings => Variables => D1 Bindings ) So, may be it's not only a lap problem, but may be a kind of « refresh » bindings in a currently used worker ?
Max (@rozenmd)
Max (@rozenmd)•13mo ago
In the same worker, are you trying to create a database, update the worker's own bindings, then try do something with that database?
GuillaumeLakano
GuillaumeLakanoOP•13mo ago
The code is like this: worker « signup » call the CF API to create D1 DB + GET/PUT Script settings of worker « d1-bindings », then call the service worker « d1 » to launch the batch ( create table, insert ... ) and worker « d1 » will call the service worker « d1-bindings » do execute it. « d1 » service worker is a kind of ORDB with ACLs, just translate our kind of request to pure SQL code + params array. Then if the requested binding to uses is dynamic, it's sent to « d1-bindings » service worker, that will just do a very basic D1 execute call I've separated in 2 differents service workers ( « d1 » and « d1-bindings » ) because if I want to update the code of a worker where the Settings have been dynamically updated, we can't deploy new code anymore without destroying all previously associated bindings with the API ( so, as the code of « d1-bindings » is very short, I'll not deploy it anymore ) Good news ! I have something that almost works, so now if the 1st SQL query is a CREATE TABLE and we need d1-binding, I wait 1s before calling d1-binding, and d1-binding return a 404 error if it's still not good, then I wait again 1s and call it again, max 10s It's not ideal, but at least it's works! And I known it's only temporary until a real DYNAMIC BINDING system is created. Also, I have randomly an AUTH error on the API ( around 1 time on 6 ) : { "debug": [ "fetchAPI: POST /d1/database failed", { "status": 403, "response": { "success": false, "errors": [ { "code": 10000, "message": "Authentication error" } ] }, "body": "{"name":"client-staging-AlfDcCo06Cyj"}" } ], "error": "bug" } It's exactly the same TOKEN each time, so there is absolutely no reason that sometime I receive a code 10000 Authentification error.
Want results from more Discord servers?
Add your server