Time Series cannot be unassigned from CWMS owned Time Series Groups
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 28
- Forks
- 25
- Avg merge
- 4d 22h
- Merged PRs (30d)
- 20
Description
Describe the bug
Its possible to assign time series to CWMS owned groups but its not possible to unassign them.
Expected behavior
These integration test in TimeSeriesGroupControllerTestIT should pass: test_patch_permissions_CWMS_with_replacement
test_patch_permissions_CWMS
To Reproduce
Steps to reproduce the behavior:
- Assign SPK timeseries to a CWMS group
- Attempt to PATCH the time series group providing the OFFICE parameter and the replace-assigned-ts=true parameter and new time series group that does not include the recently assigned time series.
- See error 500 "Database Error"
Logs/Incident Identifier
2026-03-10T01:31:09.8781236Z TimeSeriesGroupControllerTestIT (schema: 26.02.17-RC01) > TimeSeriesGroupControllerTestIT.test_patch_permissions_CWMS_with_replacement (schema: 26.02.17-RC01) > [2] / STANDARD_ERROR
2026-03-10T01:31:09.8784143Z 10-Mar-2026 01:31:09.841 WARNING [http-nio-auto-1-exec-15] cwms.cda.ApiServlet.lambda$init$8 error on request[4db16af9-eb28-40ae-a2cc-a921618bd994]: /cwms-data/timeseries/group/Default
2026-03-10T01:31:09.8786722Z org.jooq.exception.DataAccessException: SQL [{ call "CWMS_20"."CWMS_TS"."UNASSIGN_TS_GROUP" (?, ?, ?, ?, ?) }]; ORA-20048: NO_WRITE_PRIVILEGE: User doesnt have write privileges
2026-03-10T01:31:09.8788503Z ORA-06512: at "CWMS_20.CWMS_ERR", line 80
2026-03-10T01:31:09.8789372Z ORA-06512: at "CWMS_20.ST_TS_GROUP_ASSIGNMENT", line 9
2026-03-10T01:31:09.8790141Z ORA-04088: error during execution of trigger 'CWMS_20.ST_TS_GROUP_ASSIGNMENT'
2026-03-10T01:31:09.8790973Z ORA-06512: at "CWMS_20.CWMS_TS", line 10803
2026-03-10T01:31:09.8791428Z ORA-06512: at line 1
2026-03-10T01:31:09.8791662Z
2026-03-10T01:31:09.8791881Z at org.jooq_3.18.7.ORACLE18C.debug(Unknown Source)
2026-03-10T01:31:09.8792633Z at org.jooq.impl.Tools.translate(Tools.java:3470)
2026-03-10T01:31:09.8793232Z at org.jooq.impl.Tools.translate(Tools.java:3458)
2026-03-10T01:31:09.8794065Z at org.jooq.impl.DefaultExecuteContext.sqlException(DefaultExecuteContext.java:802)
2026-03-10T01:31:09.8795152Z at org.jooq.impl.AbstractRoutine.executeCallableStatement(AbstractRoutine.java:611)
2026-03-10T01:31:09.8796105Z at org.jooq.impl.AbstractRoutine.execute(AbstractRoutine.java:405)
2026-03-10T01:31:09.8796784Z at org.jooq.impl.Tools.attach(Tools.java:1610)
2026-03-10T01:31:09.8797927Z at org.jooq.impl.AbstractRoutine.execute(AbstractRoutine.java:374)
2026-03-10T01:31:09.8798960Z at usace.cwms.db.jooq.codegen.packages.CWMS_TS_PACKAGE.call_UNASSIGN_TS_GROUP(CWMS_TS_PACKAGE.java:8553)
2026-03-10T01:31:09.8800109Z at cwms.cda.data.dao.TimeSeriesGroupDao.unassignForOffice(TimeSeriesGroupDao.java:404)
2026-03-10T01:31:09.8801432Z at cwms.cda.data.dao.TimeSeriesGroupDao.lambda$unassignForOffice$7(TimeSeriesGroupDao.java:396)
2026-03-10T01:31:09.8802713Z at org.jooq.impl.DefaultDSLContext.lambda$connection$12(DefaultDSLContext.java:697)
2026-03-10T01:31:09.8803720Z at org.jooq.impl.DefaultDSLContext.connectionResult(DefaultDSLContext.java:658)
2026-03-10T01:31:09.8804824Z at org.jooq.impl.DefaultDSLContext.connection(DefaultDSLContext.java:696)
2026-03-10T01:31:09.8805624Z at cwms.cda.data.dao.JooqDao.connection(JooqDao.java:788)
2026-03-10T01:31:09.8806526Z at cwms.cda.data.dao.TimeSeriesGroupDao.unassignForOffice(TimeSeriesGroupDao.java:394)
2026-03-10T01:31:09.8807605Z at cwms.cda.api.TimeSeriesGroupController.update(TimeSeriesGroupController.java:288)
2026-03-10T01:31:09.8808562Z at io.javalin.apibuilder.CrudFunction$4.invoke$lambda-0(CrudHandler.kt:33)
2026-03-10T01:31:09.8809414Z at io.javalin.apibuilder.CrudFunctionHandler.handle(CrudHandler.kt)
2026-03-10T01:31:09.8810264Z at cwms.cda.security.CdaAccessManager.manage(CdaAccessManager.java:37)
2026-03-10T01:31:09.8811134Z at io.javalin.http.JavalinServlet.addHandler$lambda-0(JavalinServlet.kt:96)
2026-03-10T01:31:09.8812077Z at io.javalin.http.JavalinServlet$lifecycle$2$1$1.invoke(JavalinServlet.kt:43)
2026-03-10T01:31:09.8813514Z at io.javalin.http.JavalinServlet$lifecycle$2$1$1.invoke(JavalinServlet.kt:43)
2026-03-10T01:31:09.8814542Z at io.javalin.http.JavalinServletHandler.executeNextTask(JavalinServletHandler.kt:99)
2026-03-10T01:31:09.8815805Z at io.javalin.http.JavalinServletHandler.queueNextTaskOrFinish$lambda-1(JavalinServletHandler.kt:85)
2026-03-10T01:31:09.8817089Z at java.base/java.util.concurrent.CompletableFuture.uniComposeStage(CompletableFuture.java:1106)
2026-03-10T01:31:09.8818269Z at java.base/java.util.concurrent.CompletableFuture.thenCompose(CompletableFuture.java:2241)
2026-03-10T01:31:09.8819553Z at io.javalin.http.JavalinServletHandler.queueNextTaskOrFinish$javalin(JavalinServletHandler.kt:85)
2026-03-10T01:31:09.8820952Z at io.javalin.http.JavalinServletHandler.executeNextTask$lambda-11$lambda-10(JavalinServletHandler.kt:119)
2026-03-10T01:31:09.8822540Z at java.base/java.util.concurrent.CompletableFuture.uniApplyNow(CompletableFuture.java:680)
2026-03-10T01:31:09.8823807Z at java.base/java.util.concurrent.CompletableFuture.uniApplyStage(CompletableFuture.java:658)
2026-03-10T01:31:09.8825093Z at java.base/java.util.concurrent.CompletableFuture.thenApply(CompletableFuture.java:2100)
2026-03-10T01:31:09.8826282Z at io.javalin.http.JavalinServletHandler.executeNextTask(JavalinServletHandler.kt:119)
2026-03-10T01:31:09.8827606Z at io.javalin.http.JavalinServletHandler.queueNextTaskOrFinish$lambda-1(JavalinServletHandler.kt:85)
2026-03-10T01:31:09.8828958Z at java.base/java.util.concurrent.CompletableFuture.uniComposeStage(CompletableFuture.java:1106)
2026-03-10T01:31:09.8830197Z at java.base/java.util.concurrent.CompletableFuture.thenCompose(CompletableFuture.java:2241)
2026-03-10T01:31:09.8831483Z at io.javalin.http.JavalinServletHandler.queueNextTaskOrFinish$javalin(JavalinServletHandler.kt:85)
2026-03-10T01:31:09.8833045Z at io.javalin.http.JavalinServletHandler.executeNextTask$lambda-11$lambda-10(JavalinServletHandler.kt:119)
2026-03-10T01:31:09.8834360Z at java.base/java.util.concurrent.CompletableFuture.uniApplyNow(CompletableFuture.java:680)
2026-03-10T01:31:09.8835583Z at java.base/java.util.concurrent.CompletableFuture.uniApplyStage(CompletableFuture.java:658)
2026-03-10T01:31:09.8837196Z at java.base/java.util.concurrent.CompletableFuture.thenApply(CompletableFuture.java:2100)
2026-03-10T01:31:09.8838403Z at io.javalin.http.JavalinServletHandler.executeNextTask(JavalinServletHandler.kt:119)
2026-03-10T01:31:09.8839659Z at io.javalin.http.JavalinServletHandler.queueNextTaskOrFinish$lambda-1(JavalinServletHandler.kt:85)
2026-03-10T01:31:09.8840948Z at java.base/java.util.concurrent.CompletableFuture.uniComposeStage(CompletableFuture.java:1106)
2026-03-10T01:31:09.8842161Z at java.base/java.util.concurrent.CompletableFuture.thenCompose(CompletableFuture.java:2241)
2026-03-10T01:31:09.8843612Z at io.javalin.http.JavalinServletHandler.queueNextTaskOrFinish$javalin(JavalinServletHandler.kt:85)
2026-03-10T01:31:09.8844812Z at io.javalin.http.JavalinServlet.service(JavalinServlet.kt:89)
2026-03-10T01:31:09.8845588Z at javax.servlet.http.HttpServlet.service(HttpServlet.java:623)
2026-03-10T01:31:09.8846287Z at cwms.cda.ApiServlet.service(ApiServlet.java:947)
2026-03-10T01:31:09.8846969Z at javax.servlet.http.HttpServlet.service(HttpServlet.java:623)
2026-03-10T01:31:09.8847965Z at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:197)
2026-03-10T01:31:09.8849179Z at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:142)
2026-03-10T01:31:09.8850412Z at org.apache.catalina.filters.HttpHeaderSecurityFilter.doFilter(HttpHeaderSecurityFilter.java:129)
2026-03-10T01:31:09.8851763Z at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:166)
2026-03-10T01:31:09.8853225Z at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:142)
2026-03-10T01:31:09.8854319Z at org.apache.catalina.filters.CorsFilter.handleNonCORS(CorsFilter.java:334)
2026-03-10T01:31:09.8855257Z at org.apache.catalina.filters.CorsFilter.doFilter(CorsFilter.java:161)
2026-03-10T01:31:09.8856393Z at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:166)
2026-03-10T01:31:09.8857799Z at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:142)
2026-03-10T01:31:09.8858956Z at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:166)
2026-03-10T01:31:09.8860134Z at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:88)
2026-03-10T01:31:09.8861218Z at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:481)
2026-03-10T01:31:09.8862190Z at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
2026-03-10T01:31:09.8863285Z at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:83)
2026-03-10T01:31:09.8864199Z at org.apache.catalina.authenticator.SingleSignOn.invoke(SingleSignOn.java:240)
2026-03-10T01:31:09.8865085Z at fixtures.tomcat.SingleSignOnWrapper.invoke(SingleSignOnWrapper.java:21)
2026-03-10T01:31:09.8866108Z at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:72)
2026-03-10T01:31:09.8867166Z at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344)
2026-03-10T01:31:09.8868167Z at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:398)
2026-03-10T01:31:09.8869173Z at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
2026-03-10T01:31:09.8870263Z at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:935)
2026-03-10T01:31:09.8871680Z at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1831)
2026-03-10T01:31:09.8872957Z at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
2026-03-10T01:31:09.8874051Z at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:973)
2026-03-10T01:31:09.8875566Z at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:491)
2026-03-10T01:31:09.8876636Z at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
2026-03-10T01:31:09.8877439Z at java.base/java.lang.Thread.run(Thread.java:829)
2026-03-10T01:31:09.8878272Z Caused by: java.sql.SQLException: ORA-20048: NO_WRITE_PRIVILEGE: User doesnt have write privileges
2026-03-10T01:31:09.8879081Z ORA-06512: at "CWMS_20.CWMS_ERR", line 80
2026-03-10T01:31:09.8879605Z ORA-06512: at "CWMS_20.ST_TS_GROUP_ASSIGNMENT", line 9
2026-03-10T01:31:09.8880310Z ORA-04088: error during execution of trigger 'CWMS_20.ST_TS_GROUP_ASSIGNMENT'
2026-03-10T01:31:09.8880979Z ORA-06512: at "CWMS_20.CWMS_TS", line 10803
2026-03-10T01:31:09.8881554Z ORA-06512: at line 1
2026-03-10T01:31:09.8881776Z
2026-03-10T01:31:09.8882107Z at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:509)
2026-03-10T01:31:09.8883124Z at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:461)
2026-03-10T01:31:09.8883889Z at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:1104)
2026-03-10T01:31:09.8884603Z at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:550)
2026-03-10T01:31:09.8885299Z at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:268)
2026-03-10T01:31:09.8885956Z at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:655)
2026-03-10T01:31:09.8886761Z at oracle.jdbc.driver.T4CCallableStatement.doOall8(T4CCallableStatement.java:265)
2026-03-10T01:31:09.8887752Z at oracle.jdbc.driver.T4CCallableStatement.doOall8(T4CCallableStatement.java:86)
2026-03-10T01:31:09.8888780Z at oracle.jdbc.driver.T4CCallableStatement.executeForRows(T4CCallableStatement.java:965)
2026-03-10T01:31:09.8889904Z at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1205)
2026-03-10T01:31:09.8891060Z at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3666)
2026-03-10T01:31:09.8892673Z at oracle.jdbc.driver.T4CCallableStatement.executeInternal(T4CCallableStatement.java:1358)
2026-03-10T01:31:09.8893828Z at oracle.jdbc.driver.OraclePreparedStatement.execute(OraclePreparedStatement.java:3778)
2026-03-10T01:31:09.8894977Z at oracle.jdbc.driver.OracleCallableStatement.execute(OracleCallableStatement.java:4251)
2026-03-10T01:31:09.8896231Z at oracle.jdbc.driver.OraclePreparedStatementWrapper.execute(OraclePreparedStatementWrapper.java:1081)
2026-03-10T01:31:09.8897369Z at jdk.internal.reflect.GeneratedMethodAccessor46.invoke(Unknown Source)
2026-03-10T01:31:09.8898538Z at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
2026-03-10T01:31:09.8899650Z at java.base/java.lang.reflect.Method.invoke(Method.java:566)
2026-03-10T01:31:09.8900768Z at org.apache.tomcat.jdbc.pool.interceptor.AbstractQueryReport$StatementProxy.invoke(AbstractQueryReport.java:214)
2026-03-10T01:31:09.8901806Z at com.sun.proxy.$Proxy65.execute(Unknown Source)
2026-03-10T01:31:09.8902724Z at jdk.internal.reflect.GeneratedMethodAccessor46.invoke(Unknown Source)
2026-03-10T01:31:09.8903900Z at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
2026-03-10T01:31:09.8904985Z at java.base/java.lang.reflect.Method.invoke(Method.java:566)
2026-03-10T01:31:09.8906071Z at org.apache.tomcat.jdbc.pool.interceptor.AbstractQueryReport$StatementProxy.invoke(AbstractQueryReport.java:214)
2026-03-10T01:31:09.8907086Z at com.sun.proxy.$Proxy65.execute(Unknown Source)
2026-03-10T01:31:09.8907821Z at jdk.internal.reflect.GeneratedMethodAccessor46.invoke(Unknown Source)
2026-03-10T01:31:09.8908995Z at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
2026-03-10T01:31:09.8910058Z at java.base/java.lang.reflect.Method.invoke(Method.java:566)
2026-03-10T01:31:09.8911723Z at org.apache.tomcat.jdbc.pool.interceptor.StatementDecoratorInterceptor$StatementProxy.invoke(StatementDecoratorInterceptor.java:237)
2026-03-10T01:31:09.8913198Z at com.sun.proxy.$Proxy65.execute(Unknown Source)
2026-03-10T01:31:09.8913950Z at jdk.internal.reflect.GeneratedMethodAccessor46.invoke(Unknown Source)
2026-03-10T01:31:09.8915109Z at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
2026-03-10T01:31:09.8916183Z at java.base/java.lang.reflect.Method.invoke(Method.java:566)
2026-03-10T01:31:09.8917127Z at org.apache.tomcat.jdbc.pool.StatementFacade$StatementProxy.invoke(StatementFacade.java:123)
2026-03-10T01:31:09.8918161Z at com.sun.proxy.$Proxy65.execute(Unknown Source)
2026-03-10T01:31:09.8919023Z at org.jooq.tools.jdbc.DefaultPreparedStatement.execute(DefaultPreparedStatement.java:219)
2026-03-10T01:31:09.8920116Z at org.jooq.impl.Tools.executeStatementAndGetFirstResultSet(Tools.java:4695)
2026-03-10T01:31:09.8921030Z at org.jooq.impl.AbstractRoutine.execute0(AbstractRoutine.java:622)
2026-03-10T01:31:09.8921910Z at org.jooq.impl.AbstractRoutine.executeCallableStatement(AbstractRoutine.java:582)
2026-03-10T01:31:09.8922778Z ... 72 more
2026-03-10T01:31:09.8924210Z Caused by: Error : 20048, Position : 0, Sql = BEGIN "CWMS_20"."CWMS_TS"."UNASSIGN_TS_GROUP" (:1 , :2 , :3 , :4 , :5 ) ; END;, OriginalSql = { call "CWMS_20"."CWMS_TS"."UNASSIGN_TS_GROUP" (?, ?, ?, ?, ?) }, Error Msg = ORA-20048: NO_WRITE_PRIVILEGE: User doesnt have write privileges
2026-03-10T01:31:09.8925983Z ORA-06512: at "CWMS_20.CWMS_ERR", line 80
2026-03-10T01:31:09.8926526Z ORA-06512: at "CWMS_20.ST_TS_GROUP_ASSIGNMENT", line 9
2026-03-10T01:31:09.8927243Z ORA-04088: error during execution of trigger 'CWMS_20.ST_TS_GROUP_ASSIGNMENT'
2026-03-10T01:31:09.8927923Z ORA-06512: at "CWMS_20.CWMS_TS", line 10803
2026-03-10T01:31:09.8928401Z ORA-06512: at line 1
2026-03-10T01:31:09.8928637Z
2026-03-10T01:31:09.8928986Z at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:513)
2026-03-10T01:31:09.8929603Z ... 110 more
2026-03-10T01:31:09.8929791Z
CURL Commands
The issue is easier to reproduce from IT
CDA Version (please complete the following information):
Happens in release (25.07.01), latest and next-release
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with TimeSeriesGroupControllerTestIT, especially test_patch_permissions_CWMS_with_replacement and test_patch_permissions_CWMS, to reproduce the failed unassignment. Trace the request through TimeSeriesGroupController.update and TimeSeriesGroupDao.unassignForOffice, including the CWMS_TS UNASSIGN_TS_GROUP call and reported NO_WRITE_PRIVILEGE error. Done means both tests pass when a CWMS-owned group is patched without a previously assigned time series.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, sql
- Domain
- api, backend, databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100