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
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
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()`Can you log
settings
and see what that looks like?The PATCH only works if I don't keep the old content of the bindings settings
After you push the
newBinding
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
At a glance
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 ?
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 }));
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
my « settings » var contains something like : { bindings: [...], limits: { ... }, ... }, seems to be the good format, isn't it ?
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 })
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, .... ) ?
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 APIok, 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 ^^
So there's
id
in the documentation but the actual API request returns database_id
?exactly
don't suppose you know about this, are they treated as aliases for one another? Wrangler uses
id
in the upload requestit'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 »
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?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 )
I suspect the error comes from
database_id
in the existing bindings
There might be other bindings which have the wrong keys tooyep it's a good guess, but this also means it's not consistent between the different API calls ( PATCH / GET )
If that's the case, then we'd just try and get the
GET
calls fixed.I'll try to rename each keys name « database_id » => « id » and let you known
id
is definitely correct, as Wrangler and the API have used that forever.CC @elithrar fyi, some inconsistency between API call methods for what we call
database_id
in bindingsThanks Max!
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
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
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 ?
In the same worker, are you trying to create a database, update the worker's own bindings, then try do something with that database?
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.