Semántica de ejecución, restricciones y seguridad

Esta página resume cómo se comporta un Script en tiempo de ejecución (orden, transacciones, errores, bloqueo), a qué restricciones estáticas está sujeto al guardarse y su modelo de seguridad. Para la sintaxis, consulte el Catálogo de Statement y las Expresiones de valor; para combinaciones prácticas, consulte el Cookbook.

Orden de ejecución

  • Los statements se ejecutan secuencialmente de arriba abajo. Cuando la ejecución alcanza un Return, termina en ese punto.
  • La ejecución ocurre en línea, en la ruta que atiende la petición de la llamada. La respuesta de la llamada es el resultado de la ejecución (para la forma de la respuesta, consulte Petición y respuesta en la descripción general de Script), y el tiempo que recibe una ejecución se trata más abajo en Presupuesto de tiempo.

Semántica de ejecución

Guard (condiciones previas)

No existe un Statement guard dedicado. Se expresa con If y then:[Return]. Cuando se incumple la condición, devuelve un resultado y no ejecuta los Statement siguientes (por supuesto, también es posible un Script sin guard).

{ "type": "If", "condition": { "<": [ "{ /wallet/fields/balance/en-US }", "{ /payload/fields/cost }" ] },
  "then": [ { "type": "Return", "value": { "ok": false, "reason": "insufficient credit" }, "statusCode": 402 } ] }

Sin transacciones y compensación best-effort

Un Script no es una transacción. Ante un fallo, el motor intenta compensar el trabajo realizado hasta ese momento y devuelve la causa del error, pero con las siguientes limitaciones (asumidas por diseño).

  • Deshacer un borrado crea un nuevo sys.id, por lo que las referencias que apuntaban a él se rompen.
  • Los efectos externos (Http) son irreversibles (una llamada que ya ha salido, y su cobro, no se pueden deshacer).
  • Si la compensación no se ejecuta en absoluto, puede quedar un estado no compensado.

Si necesita atomicidad real, escriba la compensación en el Script usted mismo o coloque las operaciones irreversibles (como las llamadas externas) al final. El orden más peligroso es el que «encadena hasta el final pero no puede revertirse, y aun así parece seguro».

Bloqueo optimista

La contención de update/patch se acota con version en ResourceUpdate y ResourcePatch. Si se proporciona version (una expresión de valor, Int), la actualización se realiza solo cuando coincide con el sys.version actual del destino; una discrepancia aborta con un error de conflicto de versión (que se puede manejar localmente con Try/catch). Si se omite, es last-write-wins sin comprobación. Normalmente se lee primero con ResourceRead o ResourceFind y se pasa ese sys.version (véase CAS de bloqueo optimista en el Cookbook).

Escrituras en origin

Las escrituras siempre se aplican en origin (draft), y la exposición en delivery (CDA/ACDA) se controla con publish (el publish de ResourceCreate/ResourceUpdate/ResourcePatch, o ResourcePublish/ResourceUnpublish).

Qué se considera un fallo

Si un Statement falla durante la ejecución, la ejecución se interrumpe en ese punto, salvo que haya un Try que gestione ese fallo. En ese momento, el motor intenta deshacer el trabajo realizado hasta entonces. Deshacerlo tiene limitaciones, y los detalles se tratan en Sin transacciones y compensación best-effort.

Si el Statement que ha fallado está dentro de un Try, ese fallo se puede gestionar en catch. Dentro de un catch, se referencia el contenido del fallo ({ message }) mediante /error. No se incluye en qué Statement se produjo el fallo.

Se consideran fallos los casos siguientes.

Return no es un fallo. Termina la ejecución de forma anticipada y normal, así que no pasa a catch.

Las dos maneras en que falla Http

Los fallos de Http se dividen en dos según se traten o no como una respuesta de status. Según esta diferencia, cambia si se aplican retry e ignoreStatusCode.

TipoCasos tratados como respuesta de statusCasos que fallan de inmediato
Casos incluidosLa API de destino responde con un status de 400 o superior, se agota el tiempo de espera (status 504), no se puede conectar con la API de destino o no se puede leer la respuesta (status 502), el cuerpo de respuesta supera los 10MiB (status 502)responseType es "Json" pero el cuerpo de una respuesta correcta no es JSON, el archivo que se va a enviar supera el límite de descarga, la URL del archivo responde con un status distinto de 2xx o no se puede conectar con la URL del archivo, el formato del valor de una part es incorrecto
retrySe reintenta el número de veces indicadoNo se reintenta
ignoreStatusCode: trueNo se considera un fallo y se vincula { status, body } como resultadoNo se aplica y se trata como fallo
Try/catchSe puede gestionar en catchSe puede gestionar en catch

Las condiciones en que falla el proceso de envío de archivos se tratan en detalle en Enviar un archivo como cuerpo.

En el servidor solo se agrega el recuento

El recuento lo hace ResourceCount en el servidor. Como no trae los elementos, no queda sujeto al máximo de elementos procesados.

Para sum y group-by no hay operaciones de servidor dedicadas. Esas agregaciones hay que calcularlas a mano recorriendo con ResourceForEach y usando SetVar y JsonLogic, por lo que quedan limitadas por el máximo de elementos procesados (no es adecuado para agregar millones de registros). Si solo hace falta el recuento, no se recorre: se usa ResourceCount.

Sin espera ni retardo

Un Script no tiene el Statement Delay. Un Script se ejecuta una sola vez y termina, y no espera ni sondea internamente a que termine un job externo.

Restricciones estáticas (validadas al guardar)

Lo siguiente se comprueba cuando se guarda un Script (al crear/actualizar). Si algo se incumple, se rechaza el guardado (falla en el momento de la autoría, no en tiempo de ejecución). Con qué código se rechaza cada infracción se trata en Errores.

RestricciónValor
Máximo de llamadas externas (Http, EmailSend) por definiciónSegún el plan (véase Planes de precios)
Máximo total de elementos procesados por ResourceForEach (si no hay limit declarado, recorre hasta este valor; si llega a él quedando coincidencias, falla)10.000
Máximo de SetVar por definición (anidados incluidos)10
Máximo de Cache por definición (anidados incluidos, sumando con independencia de la operación)5. Si se supera, guardado rechazado
Un Cache dentro del bloque de un Loop o de un ResourceForEachGuardado rechazado
Cache.keySolo literal, 128 caracteres como máximo. Si es una expresión de valor, guardado rechazado
Cache.ttlEntre 1 y 30 segundos; si se omite, 5 segundos. Fuera de ese rango, guardado rechazado
Máximo total de Statement por definición (anidados incluidos)Según el plan (véase Planes de precios)
Límite de Http.retry2
Campos del cuerpo de la petición de un Http (body, urlBody, multipartBody)Solo uno de los tres. Si se escriben dos o más, guardado rechazado
Número de parts de Http.multipartBody1 o más. Si está vacío, guardado rechazado
value, url de una part de multipartBodyExactamente uno. Si se escriben ambos o se dejan ambos vacíos, guardado rechazado
fileName de una part de multipartBodySolo en la part que lleva url. Si se escribe sin url, guardado rechazado
Longitud de Regex.pattern128 caracteres
Máximo de secrets por definición20
key de secretsDe 1 a 64 caracteres, solo letras del alfabeto inglés, números, _ y -. Si hay dos key iguales, guardado rechazado
value de secretsDe 1 a 4.096 caracteres. Fuera de ese rango, guardado rechazado
Referencia { /secrets… }Exactamente /secrets/<key declarada>. Si no, guardado rechazado
Statement que crean o eliminan un ServiceUserGuardado rechazado. Solo los tres Statement de lectura y ResourceUpdate y ResourcePatch aceptan este recurso
Si anonymousCallEnabled es true, el createdBy: ":self" de whereGuardado rechazado
El campo transformations de una instrucción de ingesta de Media (Transformación de archivos)Solo array. El type de cada elemento es PdfWatermark y color es #RRGGBB. text es una sola línea en la que toda la cadena escrita (incluidas las rutas de { /pointer }) está compuesta por caracteres admitidos. Si se incumple, guardado rechazado
Longitud del text literal de PdfWatermarkDe 1 a 64 caracteres. Fuera de ese rango, guardado rechazado. Un text que contiene { /pointer } no se comprueba al guardar, sino al ejecutar, con el valor resuelto

Los límites fijos de la tabla anterior son valores que fija la plataforma, así que son los mismos con independencia del plan. En cambio, el número total de Statement y el número de llamadas externas por definición son límites por plan. Estos dos no son errores de validación sino límites de plan, así que, al superarlos, el guardado o la modificación se rechazan por superación del límite del plan (la misma definición sí se permite en un plan superior) y se desbloquean actualizando el plan. Los valores por plan están en Planes de precios.

La ingesta de archivo de Media, a diferencia de las llamadas externas como Http, EmailSend, no cuenta para el límite de llamadas externas por definición.

ResourceForEach es un Statement compuesto que posee hijos, así que él mismo no cuenta en el número de llamadas externas. Son los Statement de llamada externa dentro de onEach (Http, EmailSend) los que cuentan (de forma estática cuentan como 1, pero durante el recorrido se ejecutan realmente en cada elemento). En onEach se pueden colocar llamadas externas o ingesta de archivos de Media, y lo mismo vale para el body de Loop. Cuántas veces gira realmente la iteración no entra en este recuento: entra como una multiplicación en el Presupuesto de tiempo de más abajo.

Límites de longitud de los valores (en tiempo de ejecución)

Los Statement de firma y de tratamiento de texto, y también Cache, tienen un límite superior en el tamaño de los valores que manejan. No es la longitud de la expresión, sino la longitud del valor resuelto de esa expresión (los dieciséis caracteres de { /rawPayload } pueden apuntar a decenas de KB), y por eso se comprueba durante la ejecución y no en el momento de guardar.

ObjetoLímiteSi se supera
El value de Signature65.536 caracteresEse Statement falla (status 422)
El value de Hash128 caracteresEse Statement falla (status 422)
El value de Regex10.240 caracteres (10KiB)Ese Statement falla (status 400)
El value de Cache10.240 bytes (10KiB)Ese Statement falla (status 422)
  • Los cuatro son como cualquier otro fallo en tiempo de ejecución, así que se pueden tratar de forma local con Try/catch.
  • El límite de Signature está ajustado al tamaño de cuerpo que envían los proveedores reales (un evento de pago llega a unos pocos KB, y un webhook de pedido a decenas de KB). El de Hash es mucho más estrecho porque es el lugar donde se concatenan unos cuantos campos.
  • Los 128 caracteres de Regex.pattern son la comprobación al guardar que figura en Restricciones estáticas más arriba. Esa longitud no es un mecanismo para evitar una explosión de cómputo ((a+)+$ es peligroso con solo seis caracteres). Lo que evita la explosión es la regla de escribir el patrón únicamente como literal y el presupuesto de tiempo de más abajo; lo único que promete la longitud es un tamaño que una persona pueda leer y revisar.

Presupuesto de tiempo (en tiempo de ejecución)

El tiempo permitido para una ejecución es de 180 segundos como máximo. El tiempo que se permite realmente se determina según la definición del Script (y también según el plan cuando se envían archivos), y es la base de 30 segundos más el tiempo que pueden usar las llamadas externas.

Este presupuesto se aplica a la ejecución completa. Aparte de esto, cada petición Http debe terminar dentro del timeoutMs de esa petición.

Base de 30 segundos

Todas las operaciones que no son llamadas externas, como leer y escribir recursos o recibir y procesar archivos de Media, se procesan dentro de estos 30 segundos. A un Script sin llamadas externas se le permiten 30 segundos.

Tiempo que se suma por Statement

Los tiempos de los Statement colocados en secuencia se suman todos.

StatementTiempo que se suma
HttptimeoutMs (30 segundos si no se indica). Si se envían archivos, se suma el tiempo de descarga de cada archivo (tabla de abajo), y si se ha indicado retry, el total se multiplica por el número de intentos (1 + retry)
EmailSendtimeoutMs (10 segundos si no se indica). Como no reintenta, se suma una sola vez
IfEl tiempo de la más larga entre then y else
ParallelEl tiempo de la más larga de las branches
TryLa suma de los tiempos de body, catch y finally
LoopEl tiempo de body multiplicado por maxIterations (10.000 si no se indica)
ResourceForEachEl tiempo de onEach multiplicado por limit (10.000 si no se indica)
Los demás Statement (los que no contienen otros Statement)No se suma. Se procesan dentro de la base de 30 segundos

Si no hay llamadas externas dentro de una iteración, el tiempo que se suma es 0 aunque se multiplique por el número de iteraciones. Por eso, una iteración así debe terminar dentro de la base de 30 segundos.

Tiempo de descarga por archivo

PlanTiempo de descarga
FreeUnos 5,2 segundos
BasicUnos 10,5 segundos
ProUnos 10,5 segundos
EnterpriseUnos 107,4 segundos

Este valor es el tiempo que se tarda en recibir el límite de descarga del plan a 10.000.000 bytes por segundo.

Ejemplo de cálculo

Un Script que llama a un Http que envía dos fotos en el plan Pro (timeoutMs de 30 segundos, retry 1) se calcula así.

  • Http: (30 segundos + 10,5 segundos × 2) × 2 = unos 102 segundos
  • Ejecución completa: 30 segundos + 102 segundos = unos 132 segundos

132 segundos es menos que 180 segundos, así que a este Script se le permiten 132 segundos.

Si se superan los 180 segundos

Aunque el valor calculado supere los 180 segundos, el Script se guarda y se ejecuta. Sin embargo, cuando la ejecución alcanza los 180 segundos, se interrumpe en ese punto.

Límites de cantidad por plan

El número de Script por Organization está limitado por plan.

PlanNúmero de Script
Free10
Basic30
Pro100
EnterpriseIlimitado

Con independencia de esto, el número de Statement y el número de llamadas externas (Http, EmailSend) que una definición de Script puede contener también están limitados por plan. Al guardar o modificar una definición, si se supera el límite de ese plan, se rechaza; para los valores concretos, consulte Planes de precios.

Cuando se alcanza el límite, se rechaza la creación de un nuevo Script.

Tamaño de descarga de archivos de Http

Cuando Http obtiene de una URL el archivo que va a enviar como cuerpo de la petición (urlBody, la part url de multipartBody), el tamaño que se puede recibir por cada URL de archivo está limitado por plan. Se aplica el plan de la Organization a la que pertenece el Space propietario de ese Script.

PlanTamaño máximo por URL de archivo
Free50MiB
Basic100MiB
Pro100MiB
Enterprise1GiB
  • El límite se aplica por separado a cada URL. Si hay varias parts url, cada archivo debe estar dentro de este límite.
  • Si se intenta enviar un archivo que supera el límite, ese Http falla (véase Las dos maneras en que falla Http).
  • Este límite es también la referencia del tiempo de descarga que se suma al Presupuesto de tiempo.

Modelo de seguridad

secrets

Los valores secretos, como las claves de API externas, la clave secreta de una pasarela de pago (PG), la clave de firma de un webhook o un valor de autenticación Basic … calculado de antemano, no se escriben tal cual en un Statement. Se declaran en el secrets de la definición y, en el Statement, se leen con { /secrets/<key> }. Las claves de prueba publicadas también se colocan en el mismo lugar. Así, cuando se sustituyen por las claves reales, basta con cambiar el valor en secrets y los Statement se quedan como están.

"secrets": [
  { "key": "LLM_API_KEY",            "value": "sk-...",    "description": "Clave de API para llamar al LLM" },
  { "key": "WEBHOOK_SIGNING_SECRET", "value": "whsec_...", "description": "" }
],
"statements": [
  { "type": "Http", "method": "POST", "url": "https://api.openai.com/v1/chat/completions",
    "headers": [ { "key": "Authorization", "value": "Bearer { /secrets/LLM_API_KEY }" } ],
    "body": { /* ... */ }, "name": "llm" }
]
CampoObligatorioRegla
keyObligatorioTiene de 1 a 64 caracteres y solo usa letras del alfabeto inglés, números, _ y -. Debe ser única dentro de un Script.
valueObligatorioEs una cadena de 1 a 4.096 caracteres. Como es un valor estático, no se interpreta como plantilla, así que aunque contenga { /… }, se usa literalmente.
descriptionObligatorioEs la descripción de su uso y tiene de 0 a 128 caracteres. También se admite la cadena vacía "".
  • Almacenamiento: WEEGLOO cifra el value y lo almacena de forma segura. Los Statement leen el valor original con { /secrets/<key> }.
  • Consulta: en las respuestas de la API que devuelven un Script (consulta, creación y modificación), el value se devuelve con su valor original. Los roles que pueden leer ese Script ven el valor, así que mantenga acotado el permiso de lectura. Un miembro (ServiceUser) no puede leer la definición de un Script (la consulta y la autoría son exclusivas de CMA, y en ACMA no hay API de Script).
  • Modificación: la modificación completa (PUT) reemplaza la definición entera. Si se envía sin secrets, los valores secretos declarados se eliminan, y si un Statement todavía hace referencia a ese valor con { /secrets/… }, se rechaza el guardado. Por eso, en cada modificación se envía también secrets. Basta con devolver tal cual el valor de la respuesta de consulta.
  • El valor durante la ejecución: lo que se hace con el valor leído lo decide el Statement. Si se devuelve el valor leído con Return, queda en la respuesta de la ejecución y en el ScriptLog; si se guarda en SetVar, en Cache o en un Content, queda ahí con su valor original. Envíe los valores secretos únicamente a la API externa que los necesita.
  • App Bundle: cuando un Script se empaqueta en un App Bundle, el value de secrets se oculta como ******, mientras que key y description se incluyen tal cual. El Script creado al instalar ese App Bundle tiene los valores secretos en ******, así que quien lo instala debe introducir los valores reales para que funcionen los Statement que los leen. Los valores escritos fuera de secrets (las cabeceras de Http, el secret de Signature, etc.) no se ocultan y se incluyen tal cual.

Un Script puede tener hasta 20 secrets. Las reglas del pointer se tratan en /secrets en Expresiones de valor.

Identidad de ejecución y autorización

  • Identidad de ejecución: durante la ejecución, toda operación de recurso se realiza bajo la identidad del usuario que llamó a /execute. El createdBy/updatedBy de cualquier recurso que se cree o actualice es el llamante, y un ámbito createdBy: ":self" también se resuelve respecto al llamante. La excepción es la llamada anónima. Una ejecución que entra por /execute/anonymous no tiene llamante, así que ambas cosas se resuelven respecto al autor (Llamada anónima).
  • Hay dos límites de autorización y en tiempo de ejecución el motor no vuelve a comprobar los permisos de recurso en cada Statement.
    1. En el momento de la autoría (guardado): al guardar un Script, se comprueba si el autor posee realmente los permisos de recurso y de acción que usan sus Statement. Si falta aunque sea uno, se rechaza el guardado. Es decir, un Script que contiene una operación no autorizada no se guarda en primer lugar. Los Statement que eligen un recurso pasan todos por esta comprobación, tanto los hoja como el ResourceForEach, que posee un bloque. Una definición ya guardada se vuelve a comprobar al modificarla, así que, una vez retirados los permisos, esa definición no se puede corregir y guardar.
      • El directorio de miembros (ServiceUser) no se comprueba con el mapa de permisos, sino por el eje de la configuración. Para usar resource: "ServiceUser" en los tres Statement de lectura y en ResourceUpdate y ResourcePatch, el settings del SpaceRole del autor debe tener SETTING_SERVICE_LOGIN (o SETTING_ALL) (el settings de SpaceRole). Es porque el directorio de miembros, en todas las demás vías, es un recurso que gobierna la configuración del Space.
      • Los Statement que crean o eliminan miembros no se guardan con ningún rol. Como un Script no puede crear ni eliminar miembros, el rechazo no es por falta de permisos (403), sino por un Statement mal escrito (400). Es decir, no es un hueco que se pueda cerrar añadiendo permisos. Los únicos cambios permitidos son el roleOverride y el enableLogin de ResourceUpdate y ResourcePatch (Manejar el directorio de miembros).
    2. En el momento de la llamada (/execute): solo se comprueba el permiso Execute de Script del llamante. Sin él, el resultado es 403. Una vez que pasa, los permisos de recurso por Statement no se vuelven a comprobar en tiempo de ejecución; la ejecución continúa. Funciona como el permiso de ejecución de una función en programación. Si se tiene permiso para ejecutar la función, no se vuelve a preguntar por el permiso de cada operación individual dentro de ella. La ruta de llamada anónima no tiene esta comprobación. Es porque no hay ningún llamante que comprobar, y por eso abrir esa ruta equivale a publicar un Script sin autenticación.
  • Bloqueo de la invocación directa (directCallEnabled): si el directCallEnabled del Script es false, la propia invocación directa de /execute se rechaza. Esta puerta se aplica después de pasar la comprobación del permiso Execute, por lo que bloquea incluso si se tiene el permiso Execute. Un llamante que no tenga permiso recibe un 403 antes de llegar a esta puerta. Como esta puerta existe solo en ese endpoint, la acción vinculada (script) de un Webhook y un Scheduler lo ejecutan igualmente. El valor predeterminado es true (invocación directa permitida).
  • Llamada anónima (anonymousCallEnabled): el valor predeterminado es false. Si se pone en true, solo ese Script se ejecuta también por una ruta dedicada sin autenticación (/execute/anonymous), y entonces la identidad de ejecución no es el llamante, sino el autor. De los dos límites anteriores, la comprobación en el momento de la llamada (el permiso Execute) no existe en esa ruta, así que la autenticación efectiva la hace el propio Script (verificando la firma de la petición recibida). Las condiciones para activarlo y las reglas de guardado se tratan en Llamada anónima.
  • Ámbito de propiedad: createdBy: ":self" en un filtro where significa «solo lo que ha creado el llamante actual» (por ejemplo, consultar solo la propia cartera). En un Script que permite la llamada anónima no se puede usar este filtro. Como no hay llamante y se resuelve como el autor, el sentido original de un ámbito de propiedad no se sostiene.
  • Permisos delegados (atención al autor): al combinar los dos límites anteriores, ejecutar un Script equivale a actuar con los permisos del autor delegados. El llamante solo necesita Execute, y los Statement dentro del Script se ejecutan exactamente dentro del ámbito para el que se autorizó al autor al guardar. En consecuencia, una operación de recurso que el llamante no podría realizar por sí mismo puede ocurrir igualmente a través del Script. Dado que los permisos concedidos al autor son el alcance efectivo de ese Script, decida con cuidado qué operaciones incluye en un Script.

Lista de comprobación resumida

Antes de guardar, compruebe lo siguiente.

  • Si ha activado la llamada anónima (anonymousCallEnabled), en where no hay ningún createdBy: ":self" y ha colocado al principio el Statement que verifica la petición recibida (Signature, etc.).
  • Las llamadas externas (Http, EmailSend) y el número total de Statement están dentro del límite del plan, SetVar es 10 o menos y Cache, 5 o menos.
  • Si ha usado Cache, ha escrito la key como literal y no lo ha colocado dentro de un Loop ni de un ResourceForEach.
  • Si recorre un conjunto grande con ResourceForEach, ha declarado un limit o ha comprobado que el tamaño se puede recorrer por completo.
  • Si ha incluido una iteración (Loop, ResourceForEach), ha comprobado que esa iteración entra como una multiplicación en el Presupuesto de tiempo (si no hay llamadas externas, el límite es el presupuesto base de 30 segundos).
  • Los valores secretos, como las claves de API externas o las claves de firma, se han declarado en secrets y se han leído con { /secrets/<key> }. No hay ningún valor secreto escrito tal cual en un Statement.
  • Si guarda con una modificación completa (PUT), ha enviado también secrets.
  • El mensaje que se usa para verificar la firma se ha tomado con { /rawPayload }, no con /payload.
  • Si hay Statement que manejan miembros (ServiceUser), el autor tiene SETTING_SERVICE_LOGIN y no ha incluido Statement que creen ni eliminen ese recurso.
  • Las operaciones irreversibles (llamadas externas) se han colocado lo más tarde posible.
  • Si envía archivos con Http, ha escrito un solo campo del cuerpo de la petición (body, urlBody, multipartBody) y ha comprobado que cada archivo está dentro del límite de descarga por plan.
  • Si preocupa la contención de update/patch, se usa version en ResourceUpdate o ResourcePatch.
  • Para devolver un resultado, se ha especificado Return.value.

Errores

Códigos que aparecen cuando la forma de la definición infringe una restricción estática y el guardado se rechaza. Los códigos por infringir las reglas de las expresiones de valor están en los errores de Expresiones de valor, y los códigos que aparecen al invocar o eliminar, en los errores de los endpoints. Para los códigos comunes a todos los recursos, consulte Errores comunes.

CódigoCondición
WGL400066La definición contiene más de 5 Statement Cache.
WGL400068La definición coloca un Statement Cache dentro del bloque de un Loop o de un ResourceForEach.
WGL400067El key de un Statement Cache lleva una referencia { /pointer } en lugar de un literal.
WGL400065El ttl de un Statement Cache queda fuera del rango permitido.
WGL400063Un Statement Cache lleva un campo que no corresponde a su action (ttl en Get, defaultValue en Set).
WGL400060El resource de un ResourceCreate, de un ResourceDelete o de un Statement de publicación o archivado lleva "ServiceUser". El directorio de miembros solo lo aceptan los tres Statement de consulta y ResourceUpdate y ResourcePatch.
WGL400077El resource de un ResourceCount lleva un recurso que no se puede contar. Media y el directorio de miembros (ServiceUser) no se pueden contar.
WGL400037Un EmailSend lleva to y toServiceUser a la vez, o los dos vacíos. Se indica exactamente uno.
WGL400054El total de destinatarios de un EmailSend (to 1 + cc + bcc) supera los 50.
WGL400039El timeoutMs de un EmailSend supera el límite superior.
WGL400101Un EmailSend lleva body y templateBody a la vez, o los dos vacíos. Se indica exactamente uno.
WGL400102El templateBody.source de un EmailSend no es un único puntero que señale a un Content leído por un ResourceRead o un ResourceFind de este Script. También se rechaza si hay otros caracteres delante o detrás del puntero.
WGL400061En un Script que permite la llamada anónima (anonymousCallEnabled), el where de un Statement de lectura lleva createdBy: ":self".
WGL400023La definición contiene más de 10 Statement SetVar.
WGL400026El retry de un Statement Http supera el límite máximo de 2.
WGL400087Un Http lleva dos o más campos del cuerpo de la petición (body, urlBody, multipartBody).
WGL400088El multipartBody de un Http no tiene ninguna part.
WGL400089Una part de multipartBody lleva value y url a la vez, o no lleva ninguno de los dos.
WGL400090Una part de multipartBody lleva fileName sin url.
WGL400036Un ResourceForEach supera el límite máximo de elementos que puede procesar.
WGL400094En secrets hay dos o más elementos con la misma key.
WGL400095La definición contiene más de 20 secrets.
WGL400086El value de un elemento de secrets queda fuera del rango de 1 a 4.096 caracteres. El error no incluye el value.
WGL400086El text de un PdfWatermark sin { /pointer } queda fuera del rango de 1 a 64 caracteres.
WGL400096El campo transformations de una instrucción de ingesta de Media no es un array, el type de un elemento no es PdfWatermark, un PdfWatermark no tiene text o su text es un objeto o un array, color no tiene el formato #RRGGBB, o el text tal como está escrito contiene caracteres no admitidos o saltos de línea.
WGL429005El número total de Statement de la definición supera el límite del plan de precios.
WGL429006El número de llamadas externas (Http, EmailSend) de la definición supera el límite del plan de precios.
WGL403015El autor no tiene los permisos de recurso y de acción que usan los Statement de la definición. Aunque tenga el permiso, se rechaza si esa regla Allow lleva un filtro contentType, createdBy o tag. Tiene que ser una regla Allow sin condiciones. La única excepción es el Create de Content: en ese caso también se acepta una regla Allow acotada por contentType, que se contrasta con el contentType escrito en el Statement (el Create de Media no tiene esta excepción). Este código cubre también el caso en que el resource de un Statement de lectura lleva "ServiceUser" y el autor no tiene SETTING_SERVICE_LOGIN.