passbolt/passbolt_api · error · InternalErrorException

Could not save the tags, try again later.

Error message

Could not save the tags, try again later. {exceptionMessage}

What it means

Thrown by ResourcesTagsAddService::add when the tags save throws a generic (non-persistence) Exception; the message is 'Could not save the tags, try again later.' plus the original exception message, rethrown as InternalErrorException (500). It signals an unexpected infrastructure-level failure rather than client validation.

Solutions

  1. Read the appended exceptionMessage to identify the underlying database exception.
  2. Retry the request — the message explicitly advises trying again later.
  3. Verify database connectivity and schema migrations are up to date (ddev refresh / run migrations).
  4. If persistent, check server logs for SQL errors and fix the schema or data causing them.
Defensive patterns

Strategy: retry

Try / catch

try { addTags(...) } catch (InternalErrorException $e) { retryWithBackoff(3); checkDbHealth(); }

Prevention

When it happens

Trigger: Database connection loss, SQL errors, transaction failures, or any unexpected Exception during saveOrFail of the resource with associated tags.

Common situations: DB outages or failovers during the request; MySQL/Postgres constraint or syntax errors from schema drift; resource contention/timeouts.

Related errors


AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17). Data as JSON: /api/errors/b6fa6146667d8ba7. Report an issue: GitHub.

Appendix: source

Thrown at plugins/PassboltEe/Tags/src/Service/Tags/ResourcesTagsAddService.php:89

        // Mark modified as dirty to prevent TimestampBehavior from updating it.
        // Tags are not part of the resource itself and should not affect the resource's modified timestamp.
        // @see https://book.cakephp.org/5/en/orm/behaviors/timestamp.html#using-the-timestamp-behavior
        $resource->setDirty('modified');

        $saveOptions = ['associated' => ['Tags', 'Tags._joinData']];
        try {
            $this->Resources->saveOrFail($resource, $saveOptions);
        } catch (PersistenceFailedException $e) { // @phpstan-ignore-line
            throw new ValidationException(
                __('Could not save the tags, try again later.'),
                $resource,
                $this->Resources
            );
        } catch (Exception $e) {
            $msg = __('Could not save the tags, try again later.');
            $msg .= ' ' . $e->getMessage();
            throw new InternalErrorException($msg, null, $e);
        }

        $this->Tags->deleteAllUnusedTags();

        $options = ['contain' => ['tag' => 1, 'permission' => 1]];
        $resource = $this->Resources->findView($uac->getId(), $resource->id, $options)->first();

        return $resource->get('tags');
    }

    /**
     * Patch the resource tags entities of a resource for a given user.
     *
     * @param \App\Utility\UserAccessControl $uac User access control.
     * @param \App\Model\Entity\Resource $resource The resource to patch the tags for
     * @param array $data The list
     * @return void
     */

View on GitHub (pinned to 31c1bbc10f)